瀏覽代碼

Merge branch 'feature/2-docs-for-cientos' of https://github.com/Tresjs/tres into feature/2-docs-for-cientos

Jaime A Torrealba C 2 年之前
父節點
當前提交
3a1b6690ed
共有 42 個文件被更改,包括 3209 次插入1644 次删除
  1. 1 1
      CONTRIBUTING.md
  2. 1 1
      README.md
  3. 336 198
      docs/.vitepress/cache/deps/@stackblitz_sdk.js
  4. 0 1
      docs/.vitepress/cache/deps/@stackblitz_sdk.js.map
  5. 548 553
      docs/.vitepress/cache/deps/@vueuse_core.js
  6. 0 1
      docs/.vitepress/cache/deps/@vueuse_core.js.map
  7. 1 1
      docs/.vitepress/cache/deps/_metadata.json
  8. 88 0
      docs/.vitepress/cache/deps/chunk-US7RK326.js
  9. 3 0
      docs/.vitepress/cache/deps/chunk-US7RK326.js.map
  10. 836 563
      docs/.vitepress/cache/deps/three.js
  11. 0 1
      docs/.vitepress/cache/deps/three.js.map
  12. 4 4
      docs/.vitepress/cache/deps/vue.js
  13. 21 9
      docs/.vitepress/config.ts
  14. 1 8
      docs/.vitepress/theme/components/FirstScene.vue
  15. 30 0
      docs/cientos/controls/orbit-controls.md
  16. 2 2
      docs/cientos/index.md
  17. 29 0
      docs/cientos/loaders/gltf-model.md
  18. 38 0
      docs/cientos/loaders/use-gltf.md
  19. 40 0
      docs/cientos/misc/use-tweakpane.md
  20. 180 0
      docs/examples/text-3d.md
  21. 13 1
      docs/guide/getting-started.md
  22. 8 7
      docs/guide/index.md
  23. 二進制
      docs/public/use-tweakpane.png
  24. 5 5
      package.json
  25. 23 0
      packages/cientos/CHANGELOG.md
  26. 11 11
      packages/cientos/package.json
  27. 5 3
      packages/cientos/src/core/Text3D.vue
  28. 2 1
      packages/cientos/src/core/useGLTF/component.ts
  29. 6 3
      packages/cientos/src/core/useGLTF/index.ts
  30. 10 8
      packages/cientos/src/core/useTweakPane/index.ts
  31. 3 3
      packages/cientos/vite.config.ts
  32. 41 0
      packages/tres/CHANGELOG.md
  33. 19 17
      packages/tres/package.json
  34. 4 24
      packages/tres/src/App.vue
  35. 119 0
      packages/tres/src/components/TheExperience.vue
  36. 85 0
      packages/tres/src/components/TheParticles.vue
  37. 86 64
      packages/tres/src/core/useInstanceCreator/index.ts
  38. 1 1
      packages/tres/src/core/useLoader/index.ts
  39. 33 34
      packages/tres/src/core/useRenderer/index.ts
  40. 1 0
      packages/tres/src/types/index.d.ts
  41. 3 0
      packages/tres/src/utils/index.ts
  42. 572 119
      pnpm-lock.yaml

+ 1 - 1
CONTRIBUTING.md

@@ -38,7 +38,7 @@ TresJS is an ecosystem of packages, each one of them has its own purpose. The ma
 
 You can go to the `packages/tres` folder and run `pnpm dev` to start the dev server. This will start a vite server that will watch for changes in the code and rebuild the package.
 
-This is only a playground to test the core package, please keep the `App.vue` file as clean as possible.
+This is only a playground to test the core package, to keep the `App.vue` clean create a new component with your scene and import it in the `App.vue` file.
 
 ### Cientos
 

+ 1 - 1
README.md

@@ -31,7 +31,7 @@ Checkout the [docs](https://tresjs.org)
 
 ## Demos
 
-- [Stackblizt Collection](https://stackblitz.com/@alvarosabu/collections/tresjs)
+- [Stackblitz Collection](https://stackblitz.com/@alvarosabu/collections/tresjs)
 
 ## Contribution
 

+ 336 - 198
docs/.vitepress/cache/deps/@stackblitz_sdk.js

@@ -1,236 +1,374 @@
 // node_modules/.pnpm/@stackblitz+sdk@1.8.2/node_modules/@stackblitz/sdk/bundles/sdk.m.js
-var e = ["angular-cli", "create-react-app", "html", "javascript", "node", "polymer", "typescript", "vue"];
-var t = { clickToLoad: function(e2) {
-  return r("ctl", e2);
-}, devToolsHeight: function(e2) {
-  return i("devtoolsheight", e2);
-}, forceEmbedLayout: function(e2) {
-  return r("embed", e2);
-}, hideDevTools: function(e2) {
-  return r("hidedevtools", e2);
-}, hideExplorer: function(e2) {
-  return r("hideExplorer", e2);
-}, hideNavigation: function(e2) {
-  return r("hideNavigation", e2);
-}, showSidebar: function(e2) {
-  return function(e3, t2) {
-    return "boolean" == typeof t2 ? "showSidebar=" + (t2 ? "1" : "0") : "";
-  }(0, e2);
-}, openFile: function(e2) {
-  return function(e3, t2) {
-    return (Array.isArray(t2) ? t2 : [t2]).filter(function(e4) {
-      return "string" == typeof e4 && "" !== e4.trim();
-    }).map(function(e4) {
-      return "file=" + encodeURIComponent(e4.trim());
-    });
-  }(0, e2).join("&");
-}, terminalHeight: function(e2) {
-  return i("terminalHeight", e2);
-}, theme: function(e2) {
-  return o("theme", ["light", "dark"], e2);
-}, view: function(e2) {
-  return o("view", ["preview", "editor"], e2);
-} };
+var e = ['angular-cli', 'create-react-app', 'html', 'javascript', 'node', 'polymer', 'typescript', 'vue']
+var t = {
+  clickToLoad: function (e2) {
+    return r('ctl', e2)
+  },
+  devToolsHeight: function (e2) {
+    return i('devtoolsheight', e2)
+  },
+  forceEmbedLayout: function (e2) {
+    return r('embed', e2)
+  },
+  hideDevTools: function (e2) {
+    return r('hidedevtools', e2)
+  },
+  hideExplorer: function (e2) {
+    return r('hideExplorer', e2)
+  },
+  hideNavigation: function (e2) {
+    return r('hideNavigation', e2)
+  },
+  showSidebar: function (e2) {
+    return (function (e3, t2) {
+      return 'boolean' == typeof t2 ? 'showSidebar=' + (t2 ? '1' : '0') : ''
+    })(0, e2)
+  },
+  openFile: function (e2) {
+    return (function (e3, t2) {
+      return (Array.isArray(t2) ? t2 : [t2])
+        .filter(function (e4) {
+          return 'string' == typeof e4 && '' !== e4.trim()
+        })
+        .map(function (e4) {
+          return 'file=' + encodeURIComponent(e4.trim())
+        })
+    })(0, e2).join('&')
+  },
+  terminalHeight: function (e2) {
+    return i('terminalHeight', e2)
+  },
+  theme: function (e2) {
+    return o('theme', ['light', 'dark'], e2)
+  },
+  view: function (e2) {
+    return o('view', ['preview', 'editor'], e2)
+  },
+}
 function n(e2) {
-  void 0 === e2 && (e2 = {});
-  var n2 = Object.entries(e2).map(function(e3) {
-    var n3 = e3[0], r2 = e3[1];
-    return null != r2 && t.hasOwnProperty(n3) ? t[n3](r2) : "";
-  }).filter(Boolean);
-  return n2.length ? "?" + n2.join("&") : "";
+  void 0 === e2 && (e2 = {})
+  var n2 = Object.entries(e2)
+    .map(function (e3) {
+      var n3 = e3[0],
+        r2 = e3[1]
+      return null != r2 && t.hasOwnProperty(n3) ? t[n3](r2) : ''
+    })
+    .filter(Boolean)
+  return n2.length ? '?' + n2.join('&') : ''
 }
 function r(e2, t2) {
-  return true === t2 ? e2 + "=1" : "";
+  return true === t2 ? e2 + '=1' : ''
 }
 function i(e2, t2) {
-  return "number" == typeof t2 && t2 >= 0 && t2 <= 100 ? e2 + "=" + Math.round(t2) : "";
+  return 'number' == typeof t2 && t2 >= 0 && t2 <= 100 ? e2 + '=' + Math.round(t2) : ''
 }
 function o(e2, t2, n2) {
-  return "string" == typeof n2 && t2.includes(n2) ? e2 + "=" + n2 : "";
+  return 'string' == typeof n2 && t2.includes(n2) ? e2 + '=' + n2 : ''
 }
 function a() {
-  return Math.random().toString(36).slice(2, 6) + Math.random().toString(36).slice(2, 6);
+  return Math.random().toString(36).slice(2, 6) + Math.random().toString(36).slice(2, 6)
 }
 function d(e2, t2) {
-  return "" + u(t2) + e2 + n(t2);
+  return '' + u(t2) + e2 + n(t2)
 }
 function c(e2, t2) {
-  var r2 = { forceEmbedLayout: true };
-  return t2 && "object" == typeof t2 && Object.assign(r2, t2), "" + u(r2) + e2 + n(r2);
+  var r2 = { forceEmbedLayout: true }
+  return t2 && 'object' == typeof t2 && Object.assign(r2, t2), '' + u(r2) + e2 + n(r2)
 }
 function u(e2) {
-  return void 0 === e2 && (e2 = {}), "string" == typeof e2.origin ? e2.origin : "https://stackblitz.com";
+  return void 0 === e2 && (e2 = {}), 'string' == typeof e2.origin ? e2.origin : 'https://stackblitz.com'
 }
 function s(e2, t2, n2) {
-  if (!t2 || !e2 || !e2.parentNode)
-    throw new Error("Invalid Element");
-  e2.id && (t2.id = e2.id), e2.className && (t2.className = e2.className), function(e3, t3) {
-    t3 && "object" == typeof t3 && (Object.hasOwnProperty.call(t3, "height") && (e3.height = "" + t3.height), Object.hasOwnProperty.call(t3, "width") && (e3.width = "" + t3.width)), e3.height || (e3.height = "300"), e3.width || e3.setAttribute("style", "width:100%;");
-  }(t2, n2), e2.parentNode.replaceChild(t2, e2);
+  if (!t2 || !e2 || !e2.parentNode) throw new Error('Invalid Element')
+  e2.id && (t2.id = e2.id),
+    e2.className && (t2.className = e2.className),
+    (function (e3, t3) {
+      t3 &&
+        'object' == typeof t3 &&
+        (Object.hasOwnProperty.call(t3, 'height') && (e3.height = '' + t3.height),
+        Object.hasOwnProperty.call(t3, 'width') && (e3.width = '' + t3.width)),
+        e3.height || (e3.height = '300'),
+        e3.width || e3.setAttribute('style', 'width:100%;')
+    })(t2, n2),
+    e2.parentNode.replaceChild(t2, e2)
 }
 function l(e2) {
-  if ("string" == typeof e2) {
-    var t2 = document.getElementById(e2);
-    if (!t2)
-      throw new Error("Could not find element with id '" + e2 + "'");
-    return t2;
+  if ('string' == typeof e2) {
+    var t2 = document.getElementById(e2)
+    if (!t2) throw new Error("Could not find element with id '" + e2 + "'")
+    return t2
   }
-  if (e2 instanceof HTMLElement)
-    return e2;
-  throw new Error("Invalid element: " + e2);
+  if (e2 instanceof HTMLElement) return e2
+  throw new Error('Invalid element: ' + e2)
 }
 function p(e2) {
-  return e2 && false === e2.newWindow ? "_self" : "_blank";
+  return e2 && false === e2.newWindow ? '_self' : '_blank'
 }
 function f() {
-  return f = Object.assign || function(e2) {
-    for (var t2 = 1; t2 < arguments.length; t2++) {
-      var n2 = arguments[t2];
-      for (var r2 in n2)
-        Object.prototype.hasOwnProperty.call(n2, r2) && (e2[r2] = n2[r2]);
-    }
-    return e2;
-  }, f.apply(this, arguments);
-}
-var h = function() {
+  return (
+    (f =
+      Object.assign ||
+      function (e2) {
+        for (var t2 = 1; t2 < arguments.length; t2++) {
+          var n2 = arguments[t2]
+          for (var r2 in n2) Object.prototype.hasOwnProperty.call(n2, r2) && (e2[r2] = n2[r2])
+        }
+        return e2
+      }),
+    f.apply(this, arguments)
+  )
+}
+var h = (function () {
   function e2(e3) {
-    this.port = void 0, this.pending = {}, this.port = e3, this.port.onmessage = this.messageListener.bind(this);
+    ;(this.port = void 0),
+      (this.pending = {}),
+      (this.port = e3),
+      (this.port.onmessage = this.messageListener.bind(this))
   }
-  var t2 = e2.prototype;
-  return t2.request = function(e3) {
-    var t3 = this, n2 = e3.type, r2 = e3.payload, i2 = a();
-    return new Promise(function(e4, o2) {
-      t3.pending[i2] = { resolve: e4, reject: o2 }, t3.port.postMessage({ type: n2, payload: f({}, r2, { __reqid: i2 }) });
-    });
-  }, t2.messageListener = function(e3) {
-    var t3;
-    if ("string" == typeof (null == (t3 = e3.data.payload) ? void 0 : t3.__reqid)) {
-      var n2 = e3.data, r2 = n2.type, i2 = n2.payload, o2 = i2.__reqid, a2 = i2.__error;
-      this.pending[o2] && (i2.__success ? this.pending[o2].resolve(function(e4) {
-        var t4 = f({}, e4);
-        return delete t4.__reqid, delete t4.__success, delete t4.__error, Object.keys(t4).length ? t4 : null;
-      }(i2)) : this.pending[o2].reject(a2 ? r2 + ": " + a2 : r2), delete this.pending[o2]);
-    }
-  }, e2;
-}();
-var m = function() {
+  var t2 = e2.prototype
+  return (
+    (t2.request = function (e3) {
+      var t3 = this,
+        n2 = e3.type,
+        r2 = e3.payload,
+        i2 = a()
+      return new Promise(function (e4, o2) {
+        ;(t3.pending[i2] = { resolve: e4, reject: o2 }),
+          t3.port.postMessage({ type: n2, payload: f({}, r2, { __reqid: i2 }) })
+      })
+    }),
+    (t2.messageListener = function (e3) {
+      var t3
+      if ('string' == typeof (null == (t3 = e3.data.payload) ? void 0 : t3.__reqid)) {
+        var n2 = e3.data,
+          r2 = n2.type,
+          i2 = n2.payload,
+          o2 = i2.__reqid,
+          a2 = i2.__error
+        this.pending[o2] &&
+          (i2.__success
+            ? this.pending[o2].resolve(
+                (function (e4) {
+                  var t4 = f({}, e4)
+                  return delete t4.__reqid, delete t4.__success, delete t4.__error, Object.keys(t4).length ? t4 : null
+                })(i2),
+              )
+            : this.pending[o2].reject(a2 ? r2 + ': ' + a2 : r2),
+          delete this.pending[o2])
+      }
+    }),
+    e2
+  )
+})()
+var m = (function () {
   function e2(e3, t3) {
-    var n2 = this;
-    this._rdc = void 0, this.editor = { openFile: function(e4) {
-      return n2._rdc.request({ type: "SDK_OPEN_FILE", payload: { path: e4 } });
-    }, setCurrentFile: function(e4) {
-      return n2._rdc.request({ type: "SDK_SET_CURRENT_FILE", payload: { path: e4 } });
-    }, setTheme: function(e4) {
-      return n2._rdc.request({ type: "SDK_SET_UI_THEME", payload: { theme: e4 } });
-    }, setView: function(e4) {
-      return n2._rdc.request({ type: "SDK_SET_UI_VIEW", payload: { view: e4 } });
-    }, showSidebar: function(e4) {
-      return void 0 === e4 && (e4 = true), n2._rdc.request({ type: "SDK_TOGGLE_SIDEBAR", payload: { visible: e4 } });
-    } }, this.preview = { origin: "", getUrl: function() {
-      return n2._rdc.request({ type: "SDK_GET_PREVIEW_URL", payload: {} }).then(function(e4) {
-        var t4;
-        return null != (t4 = null == e4 ? void 0 : e4.url) ? t4 : null;
-      });
-    }, setUrl: function(e4) {
-      if (void 0 === e4 && (e4 = "/"), "string" != typeof e4 || !e4.startsWith("/"))
-        throw new Error("Invalid argument: expected a path starting with '/', got '" + e4 + "'");
-      return n2._rdc.request({ type: "SDK_SET_PREVIEW_URL", payload: { path: e4 } });
-    } }, this._rdc = new h(e3), Object.defineProperty(this.preview, "origin", { value: "string" == typeof t3.previewOrigin ? t3.previewOrigin : null, writable: false });
+    var n2 = this
+    ;(this._rdc = void 0),
+      (this.editor = {
+        openFile: function (e4) {
+          return n2._rdc.request({ type: 'SDK_OPEN_FILE', payload: { path: e4 } })
+        },
+        setCurrentFile: function (e4) {
+          return n2._rdc.request({ type: 'SDK_SET_CURRENT_FILE', payload: { path: e4 } })
+        },
+        setTheme: function (e4) {
+          return n2._rdc.request({ type: 'SDK_SET_UI_THEME', payload: { theme: e4 } })
+        },
+        setView: function (e4) {
+          return n2._rdc.request({ type: 'SDK_SET_UI_VIEW', payload: { view: e4 } })
+        },
+        showSidebar: function (e4) {
+          return void 0 === e4 && (e4 = true), n2._rdc.request({ type: 'SDK_TOGGLE_SIDEBAR', payload: { visible: e4 } })
+        },
+      }),
+      (this.preview = {
+        origin: '',
+        getUrl: function () {
+          return n2._rdc.request({ type: 'SDK_GET_PREVIEW_URL', payload: {} }).then(function (e4) {
+            var t4
+            return null != (t4 = null == e4 ? void 0 : e4.url) ? t4 : null
+          })
+        },
+        setUrl: function (e4) {
+          if ((void 0 === e4 && (e4 = '/'), 'string' != typeof e4 || !e4.startsWith('/')))
+            throw new Error("Invalid argument: expected a path starting with '/', got '" + e4 + "'")
+          return n2._rdc.request({ type: 'SDK_SET_PREVIEW_URL', payload: { path: e4 } })
+        },
+      }),
+      (this._rdc = new h(e3)),
+      Object.defineProperty(this.preview, 'origin', {
+        value: 'string' == typeof t3.previewOrigin ? t3.previewOrigin : null,
+        writable: false,
+      })
   }
-  var t2 = e2.prototype;
-  return t2.applyFsDiff = function(e3) {
-    var t3 = function(e4) {
-      return null !== e4 && "object" == typeof e4;
-    };
-    if (!t3(e3) || !t3(e3.create))
-      throw new Error("Invalid diff object: expected diff.create to be an object.");
-    if (!Array.isArray(e3.destroy))
-      throw new Error("Invalid diff object: expected diff.create to be an array.");
-    return this._rdc.request({ type: "SDK_APPLY_FS_DIFF", payload: e3 });
-  }, t2.getDependencies = function() {
-    return this._rdc.request({ type: "SDK_GET_DEPS_SNAPSHOT", payload: {} });
-  }, t2.getFsSnapshot = function() {
-    return this._rdc.request({ type: "SDK_GET_FS_SNAPSHOT", payload: {} });
-  }, e2;
-}();
-var v = [];
-var y = function(e2) {
-  var t2 = this;
-  this.element = void 0, this.id = void 0, this.pending = void 0, this.vm = void 0, this.id = a(), this.element = e2, this.pending = new Promise(function(e3, n2) {
-    var r2 = function(n3) {
-      var r3 = n3.data;
-      "SDK_INIT_SUCCESS" === (null == r3 ? void 0 : r3.action) && r3.id === t2.id && (t2.vm = new m(n3.ports[0], r3.payload), e3(t2.vm), o2());
-    }, i2 = function() {
-      var e4;
-      null == (e4 = t2.element.contentWindow) || e4.postMessage({ action: "SDK_INIT", id: t2.id }, "*");
-    };
-    function o2() {
-      window.clearInterval(d2), window.removeEventListener("message", r2);
-    }
-    window.addEventListener("message", r2), i2();
-    var a2 = 0, d2 = window.setInterval(function() {
-      if (t2.vm)
-        o2();
-      else {
-        if (a2 >= 20)
-          return o2(), n2("Timeout: Unable to establish a connection with the StackBlitz VM"), void v.forEach(function(e4, n3) {
-            e4.id === t2.id && v.splice(n3, 1);
-          });
-        a2++, i2();
+  var t2 = e2.prototype
+  return (
+    (t2.applyFsDiff = function (e3) {
+      var t3 = function (e4) {
+        return null !== e4 && 'object' == typeof e4
+      }
+      if (!t3(e3) || !t3(e3.create)) throw new Error('Invalid diff object: expected diff.create to be an object.')
+      if (!Array.isArray(e3.destroy)) throw new Error('Invalid diff object: expected diff.create to be an array.')
+      return this._rdc.request({ type: 'SDK_APPLY_FS_DIFF', payload: e3 })
+    }),
+    (t2.getDependencies = function () {
+      return this._rdc.request({ type: 'SDK_GET_DEPS_SNAPSHOT', payload: {} })
+    }),
+    (t2.getFsSnapshot = function () {
+      return this._rdc.request({ type: 'SDK_GET_FS_SNAPSHOT', payload: {} })
+    }),
+    e2
+  )
+})()
+var v = []
+var y = function (e2) {
+  var t2 = this
+  ;(this.element = void 0),
+    (this.id = void 0),
+    (this.pending = void 0),
+    (this.vm = void 0),
+    (this.id = a()),
+    (this.element = e2),
+    (this.pending = new Promise(function (e3, n2) {
+      var r2 = function (n3) {
+          var r3 = n3.data
+          'SDK_INIT_SUCCESS' === (null == r3 ? void 0 : r3.action) &&
+            r3.id === t2.id &&
+            ((t2.vm = new m(n3.ports[0], r3.payload)), e3(t2.vm), o2())
+        },
+        i2 = function () {
+          var e4
+          null == (e4 = t2.element.contentWindow) || e4.postMessage({ action: 'SDK_INIT', id: t2.id }, '*')
+        }
+      function o2() {
+        window.clearInterval(d2), window.removeEventListener('message', r2)
       }
-    }, 500);
-  }), v.push(this);
-};
+      window.addEventListener('message', r2), i2()
+      var a2 = 0,
+        d2 = window.setInterval(function () {
+          if (t2.vm) o2()
+          else {
+            if (a2 >= 20)
+              return (
+                o2(),
+                n2('Timeout: Unable to establish a connection with the StackBlitz VM'),
+                void v.forEach(function (e4, n3) {
+                  e4.id === t2.id && v.splice(n3, 1)
+                })
+              )
+            a2++, i2()
+          }
+        }, 500)
+    })),
+    v.push(this)
+}
 function g(e2, t2) {
-  var n2 = document.createElement("input");
-  return n2.type = "hidden", n2.name = e2, n2.value = t2, n2;
+  var n2 = document.createElement('input')
+  return (n2.type = 'hidden'), (n2.name = e2), (n2.value = t2), n2
 }
 function w(t2) {
   if (!e.includes(t2.template)) {
-    var n2 = e.map(function(e2) {
-      return "'" + e2 + "'";
-    }).join(", ");
-    console.warn("Unsupported project.template: must be one of " + n2);
+    var n2 = e
+      .map(function (e2) {
+        return "'" + e2 + "'"
+      })
+      .join(', ')
+    console.warn('Unsupported project.template: must be one of ' + n2)
   }
-  var r2 = "node" === t2.template, i2 = document.createElement("form");
-  return i2.method = "POST", i2.setAttribute("style", "display:none!important;"), i2.appendChild(g("project[title]", t2.title)), i2.appendChild(g("project[description]", t2.description)), i2.appendChild(g("project[template]", t2.template)), t2.dependencies && (r2 ? console.warn("Invalid project.dependencies: dependencies must be provided as a 'package.json' file when using the 'node' template.") : i2.appendChild(g("project[dependencies]", JSON.stringify(t2.dependencies)))), t2.settings && i2.appendChild(g("project[settings]", JSON.stringify(t2.settings))), Object.keys(t2.files).forEach(function(e2) {
-    var n3 = "project[files]" + function(e3) {
-      return "[" + e3.replace(/\[/g, "%5B").replace(/\]/g, "%5D") + "]";
-    }(e2), r3 = t2.files[e2];
-    "string" == typeof r3 && i2.appendChild(g(n3, r3));
-  }), i2;
+  var r2 = 'node' === t2.template,
+    i2 = document.createElement('form')
+  return (
+    (i2.method = 'POST'),
+    i2.setAttribute('style', 'display:none!important;'),
+    i2.appendChild(g('project[title]', t2.title)),
+    i2.appendChild(g('project[description]', t2.description)),
+    i2.appendChild(g('project[template]', t2.template)),
+    t2.dependencies &&
+      (r2
+        ? console.warn(
+            "Invalid project.dependencies: dependencies must be provided as a 'package.json' file when using the 'node' template.",
+          )
+        : i2.appendChild(g('project[dependencies]', JSON.stringify(t2.dependencies)))),
+    t2.settings && i2.appendChild(g('project[settings]', JSON.stringify(t2.settings))),
+    Object.keys(t2.files).forEach(function (e2) {
+      var n3 =
+          'project[files]' +
+          (function (e3) {
+            return '[' + e3.replace(/\[/g, '%5B').replace(/\]/g, '%5D') + ']'
+          })(e2),
+        r3 = t2.files[e2]
+      'string' == typeof r3 && i2.appendChild(g(n3, r3))
+    }),
+    i2
+  )
 }
 function _(e2) {
-  var t2, n2, r2, i2;
-  return null != e2 && e2.contentWindow ? (null != (i2 = (n2 = e2) instanceof Element ? "element" : "id", t2 = null != (r2 = v.find(function(e3) {
-    return e3[i2] === n2;
-  })) ? r2 : null) ? t2 : new y(e2)).pending : Promise.reject("Provided element is not an iframe.");
-}
-var b = { connect: _, embedGithubProject: function(e2, t2, n2) {
-  var r2 = l(e2), i2 = document.createElement("iframe");
-  return i2.src = c("/github/" + t2, n2), s(r2, i2, n2), _(i2);
-}, embedProject: function(e2, t2, n2) {
-  var r2, i2 = l(e2), o2 = function(e3, t3) {
-    var n3 = w(e3);
-    return n3.action = c("/run", t3), n3.id = "sb", "<html><head><title></title></head><body>" + n3.outerHTML + "<script>document.getElementById('" + n3.id + "').submit();<\/script></body></html>";
-  }(t2, n2), a2 = document.createElement("iframe");
-  return s(i2, a2, n2), null == (r2 = a2.contentDocument) || r2.write(o2), _(a2);
-}, embedProjectId: function(e2, t2, n2) {
-  var r2 = l(e2), i2 = document.createElement("iframe");
-  return i2.src = c("/edit/" + t2, n2), s(r2, i2, n2), _(i2);
-}, openGithubProject: function(e2, t2) {
-  var n2 = d("/github/" + e2, t2), r2 = p(t2);
-  window.open(n2, r2);
-}, openProject: function(e2, t2) {
-  !function(e3, t3) {
-    var n2 = w(e3);
-    n2.action = d("/run", t3), n2.target = p(t3), document.body.appendChild(n2), n2.submit(), document.body.removeChild(n2);
-  }(e2, t2);
-}, openProjectId: function(e2, t2) {
-  var n2 = d("/edit/" + e2, t2), r2 = p(t2);
-  window.open(n2, r2);
-} };
-export {
-  b as default
-};
+  var t2, n2, r2, i2
+  return null != e2 && e2.contentWindow
+    ? (null !=
+      ((i2 = (n2 = e2) instanceof Element ? 'element' : 'id'),
+      (t2 =
+        null !=
+        (r2 = v.find(function (e3) {
+          return e3[i2] === n2
+        }))
+          ? r2
+          : null))
+        ? t2
+        : new y(e2)
+      ).pending
+    : Promise.reject('Provided element is not an iframe.')
+}
+var b = {
+  connect: _,
+  embedGithubProject: function (e2, t2, n2) {
+    var r2 = l(e2),
+      i2 = document.createElement('iframe')
+    return (i2.src = c('/github/' + t2, n2)), s(r2, i2, n2), _(i2)
+  },
+  embedProject: function (e2, t2, n2) {
+    var r2,
+      i2 = l(e2),
+      o2 = (function (e3, t3) {
+        var n3 = w(e3)
+        return (
+          (n3.action = c('/run', t3)),
+          (n3.id = 'sb'),
+          '<html><head><title></title></head><body>' +
+            n3.outerHTML +
+            "<script>document.getElementById('" +
+            n3.id +
+            "').submit();</script></body></html>"
+        )
+      })(t2, n2),
+      a2 = document.createElement('iframe')
+    return s(i2, a2, n2), null == (r2 = a2.contentDocument) || r2.write(o2), _(a2)
+  },
+  embedProjectId: function (e2, t2, n2) {
+    var r2 = l(e2),
+      i2 = document.createElement('iframe')
+    return (i2.src = c('/edit/' + t2, n2)), s(r2, i2, n2), _(i2)
+  },
+  openGithubProject: function (e2, t2) {
+    var n2 = d('/github/' + e2, t2),
+      r2 = p(t2)
+    window.open(n2, r2)
+  },
+  openProject: function (e2, t2) {
+    !(function (e3, t3) {
+      var n2 = w(e3)
+      ;(n2.action = d('/run', t3)),
+        (n2.target = p(t3)),
+        document.body.appendChild(n2),
+        n2.submit(),
+        document.body.removeChild(n2)
+    })(e2, t2)
+  },
+  openProjectId: function (e2, t2) {
+    var n2 = d('/edit/' + e2, t2),
+      r2 = p(t2)
+    window.open(n2, r2)
+  },
+}
+export { b as default }
 //# sourceMappingURL=@stackblitz_sdk.js.map

File diff suppressed because it is too large
+ 0 - 1
docs/.vitepress/cache/deps/@stackblitz_sdk.js.map


File diff suppressed because it is too large
+ 548 - 553
docs/.vitepress/cache/deps/@vueuse_core.js


File diff suppressed because it is too large
+ 0 - 1
docs/.vitepress/cache/deps/@vueuse_core.js.map


+ 1 - 1
docs/.vitepress/cache/deps/_metadata.json

@@ -38,4 +38,4 @@
       "file": "chunk-LZPJ5JBW.js"
     }
   }
-}
+}

File diff suppressed because it is too large
+ 88 - 0
docs/.vitepress/cache/deps/chunk-US7RK326.js


File diff suppressed because it is too large
+ 3 - 0
docs/.vitepress/cache/deps/chunk-US7RK326.js.map


File diff suppressed because it is too large
+ 836 - 563
docs/.vitepress/cache/deps/three.js


File diff suppressed because it is too large
+ 0 - 1
docs/.vitepress/cache/deps/three.js.map


+ 4 - 4
docs/.vitepress/cache/deps/vue.js

@@ -144,8 +144,8 @@ import {
   withKeys,
   withMemo,
   withModifiers,
-  withScopeId
-} from "./chunk-LZPJ5JBW.js";
+  withScopeId,
+} from './chunk-LZPJ5JBW.js'
 export {
   BaseTransition,
   Comment,
@@ -292,6 +292,6 @@ export {
   withKeys,
   withMemo,
   withModifiers,
-  withScopeId
-};
+  withScopeId,
+}
 //# sourceMappingURL=vue.js.map

+ 21 - 9
docs/.vitepress/config.ts

@@ -35,10 +35,11 @@ export default defineConfig({
       {
         text: 'Examples',
         items: [
-          { text: 'Orbit Controls', link: 'es/examples/orbit-controls' },
-          { text: 'Basic Animations', link: 'es/examples/basic-animations' },
-          { text: 'Load Textures', link: 'es/examples/load-textures' },
-          { text: 'Load Models', link: 'es/examples/load-models' },
+          { text: 'Orbit Controls', link: '/examples/orbit-controls' },
+          { text: 'Basic Animations', link: '/examples/basic-animations' },
+          { text: 'Load Textures', link: '/examples/load-textures' },
+          { text: 'Load Models', link: '/examples/load-models' },
+          { text: 'Load Text', link: '/examples/text-3d' },
         ],
       },
       {
@@ -53,18 +54,29 @@ export default defineConfig({
         ],
       },
       {
-        text: 'Cientos',
+        text: 'Cientos ⚡️',
         collapsible: true,
         items: [
           { text: 'Introduction', link: 'es/cientos/' },
-          {
-            text: 'Composables',
-            link: 'es/cientos/composables',
-          },
           {
             text: 'Abstractions',
             items: [{ text: 'Text3D', link: 'es/cientos/abstractions/text-3d' }],
           },
+          {
+            text: 'Controls',
+            items: [{ text: 'OrbitControls', link: '/cientos/controls/orbit-controls' }],
+          },
+          {
+            text: 'Loaders',
+            items: [
+              { text: 'useGLTF', link: '/cientos/loaders/use-gltf' },
+              { text: 'GLTFModel', link: '/cientos/loaders/gltf-model' },
+            ],
+          },
+          {
+            text: 'Misc',
+            items: [{ text: 'useTweakpane', link: '/cientos/misc/use-tweakpane' }],
+          },
         ],
       },
     ],

+ 1 - 8
docs/.vitepress/theme/components/FirstScene.vue

@@ -16,14 +16,7 @@ onMounted(() => {
 </script>
 
 <template>
-  <TresCanvas
-    clear-color="#82DBC5"
-    shadows
-    alpha
-    physically-correct-lights
-    :output-encoding="sRGBEncoding"
-    :tone-mapping="ACESFilmicToneMapping"
-  >
+  <TresCanvas clear-color="#82DBC5" shadows alpha physically-correct-lights :output-encoding="sRGBEncoding">
     <OrbitControls />
     <TresPerspectiveCamera :position="[11, 11, 11]" :fov="45" :aspect="1" :near="0.1" :far="1000" />
     <TresScene>

+ 30 - 0
docs/cientos/controls/orbit-controls.md

@@ -0,0 +1,30 @@
+# OrbitControls
+
+[OrbitControls](https://threejs.org/docs/index.html?q=orbit#examples/en/controls/OrbitControls) is a camera controller that allows you to orbit around a target. It's a great way to explore your scene.
+
+However, it is not part of the core of ThreeJS. So to use it you would need to import it from the `three/examples/jsm/controls/OrbitControls` module.
+
+Here is where the fancy part begins. ✨  
+The `cientos` package provides a component called `<OrbitControls />` that is a wrapper of the `OrbitControls` from the [`three-stdlib`](https://github.com/pmndrs/three-stdlib) module.
+
+The nicest part? You don't need to extend the catalog or pass any arguments.  
+It just works. 💯
+
+```vue{3}
+<template>
+  <TresCanvas shadows alpha>
+    <OrbitControls />
+    <TresScene> ... </TresScene>
+  </TresCanvas>
+</template>
+```
+
+## 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` |
+| **target**        | The target to orbit 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`     |

+ 2 - 2
docs/cientos/index.md

@@ -6,9 +6,9 @@
 
 ![Cientos banner](/cientos-banner.png)
 
-> Cientos (Spanish word for "hundreds", pronounced `/θjentos/` ) is is a collection of useful ready-to-go helpers and components that are not part of the [core](/docs/guide/index.md) package. The name uses the word uses in spanish to multiply by 100, to refer to the potential reach of the package to hold a amazing abstractions.
+> Cientos (Spanish word for "hundreds", pronounced `/θjentos/` ) is is a collection of useful ready-to-go helpers and components that are not part of the [core](/guide/index.md) package. The name uses the word uses in spanish to multiply by 100, to refer to the potential reach of the package to hold a amazing abstractions.
 
-The `cientos` package uses [`three-stdlib`](https://github.com/pmndrs/three-stdlib) module under the hood instead of the `three/examples/jsm` module. This means that you don't need to extend the catalogue of components using the `extend` method of the [useCatalogue](/composables/use-catalog) composable, `cientos` does it for you.
+The `cientos` package uses [`three-stdlib`](https://github.com/pmndrs/three-stdlib) module under the hood instead of the `three/examples/jsm` module. This means that you don't need to extend the catalogue of components using the `extend` method of the [useCatalogue](/api/composables#useCatalogue) composable, `cientos` does it for you.
 
 It just works. 💯
 

+ 29 - 0
docs/cientos/loaders/gltf-model.md

@@ -0,0 +1,29 @@
+# Using `GLTFModel`
+
+The `GLTFModel` component is a wrapper around [`useGLTF`](./use-gltf.md) composable and accepts the same options as props.
+
+```vue{2,10}
+<script setup lang="ts">
+import { OrbitControls, GLTFModel } from '@tresjs/cientos'
+</script>
+<template>
+  <Suspense>
+    <TresCanvas clear-color="#82DBC5" shadows alpha>
+      <TresPerspectiveCamera :position="[11, 11, 11]" />
+      <OrbitControls />
+      <TresScene>
+        <GLTFModel path="/models/AkuAku.gltf" draco />
+        <TresDirectionalLight :position="[-4, 8, 4]" :intensity="1.5" cast-shadow />
+      </TresScene>
+    </TresCanvas>
+  </Suspense>
+</template>
+```
+
+## Props
+
+| Prop          | Description                                                                                                           | Default     |
+| :------------ | :-------------------------------------------------------------------------------------------------------------------- | ----------- |
+| `path`        | Path to the model file.                                                                                               | `undefined` |
+| `draco`       | Enable [Draco compression](https://threejs.org/docs/index.html?q=drac#examples/en/loaders/DRACOLoader) for the model. | `false`     |
+| `decoderPath` | Path to a local Draco decoder.                                                                                        | `undefined` |

+ 38 - 0
docs/cientos/loaders/use-gltf.md

@@ -0,0 +1,38 @@
+# useGLTF
+
+A composable that allows you to easily load glTF models into your **TresJS** scene.
+
+## Usage
+
+```ts
+import { useGLTF } from '@tresjs/cientos'
+
+const { scene } = await useGLTF('/models/AkuAku.gltf')
+```
+
+Then is as straightforward as adding the scene to your scene:
+
+```html{4}
+<Suspense>
+  <TresCanvas shadows alpha>
+    <TresScene>
+      <TresMesh v-bind="scene" />
+    </TresScene>
+  </TresCanvas>
+</Suspense>
+```
+
+An advantage of using `useGLTF`is that you can pass a `draco` prop to enable [Draco compression](https://threejs.org/docs/index.html?q=drac#examples/en/loaders/DRACOLoader) for the model. This will reduce the size of the model and improve performance.
+
+```ts
+import { useGLTF } from '@tresjs/cientos'
+
+const { scene } = await useGLTF('/models/AkuAku.gltf', { draco: true })
+```
+
+## Options
+
+| Name            | Type      | Default     | Description                          |
+| :-------------- | --------- | ----------- | ------------------------------------ |
+| **draco**       | `boolean` | `false`     | Whether to enable Draco compression. |
+| **decoderPath** | `string`  | `undefined` | Local path to the Draco decoder.     |

+ 40 - 0
docs/cientos/misc/use-tweakpane.md

@@ -0,0 +1,40 @@
+# useTweakPane
+
+[TweakPane](https://cocopon.github.io/tweakpane/) is a JavaScript library for creating a user interface for tweaking values of JavaScript variables. It's a great tool for fine-tuning parameters and monitoring value changes on your three.js applications.
+
+**TresJS** provides a composables called `useTweakPane` that creates a Tweakpane panel to your container so you can add tweaks to it. By default, the panel is created on the top right corner of the canvas and includes a FPS graph monitor to keep and eye on the performance of your scene.
+
+::: info
+You can change the container of the panel by passing the `selector` option to the `useTweakPane` function.
+:::
+
+## Basic usage
+
+```ts
+import { useTweakPane } from '@tresjs/cientos'
+
+const { pane } = useTweakPane()
+
+const experiment = reactive({
+  clearColor: '#000000',
+  alpha: true,
+  shadow: true,
+})
+
+pane.addInput(experiment, 'clearColor', {
+  label: 'Clear Color',
+  colorMode: 'hex',
+})
+
+pane.addInput(experiment, 'alpha')
+```
+
+The result will be something like this:
+
+![](/use-tweakpane.png)
+
+## Options
+
+| Name         | Type     | Default     | Description                                                    |
+| :----------- | -------- | ----------- | -------------------------------------------------------------- |
+| **selector** | `string` | `undefined` | The selector of the container where the panel will be created. |

+ 180 - 0
docs/examples/text-3d.md

@@ -0,0 +1,180 @@
+# Text3D
+
+[TextGeometry](https://threejs.org/docs/index.html?q=text#examples/en/geometries/TextGeometry) is one of the ways we can add 3D text in our scene.
+
+<StackBlitzEmbed projectId="tresjs-text3d-cientos" />
+
+However, it is not part of the core of ThreeJS. So to use it you would need to import it from the `three/examples/jsm/controls/TextGeometry` module.
+
+This creates a problem because **TresJS** automatically creates a catalog of the core of Three so you can use them as components.
+
+Fortunately, **TresJS** provides a way to extend the catalog of components. You can do it by using the `extend` method using the [useCatalogue](/api/composables#usecatalog) composable.
+
+For more information about extending your TresJS catalog, refer to the [extending](/advanced/extending.md) section.
+
+## Using TextGeometry
+
+To use `TextGeometry` you need to import it from the `three/examples/jsm/geometries/TextGeometry` module.
+
+```js
+import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'
+```
+
+Then you need to extend the catalogue of components using the `extend` method of the [useCatalogue](/api/composables#usecatalog) composable.
+
+```js
+import { useCatalogue } from '@tresjs/core'
+import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'
+
+const { extend } = useCatalogue()
+
+extend({ TextGeometry: TextGeometry })
+```
+
+[TextGeometry](https://threejs.org/docs/index.html?q=text#examples/en/geometries/TextGeometry) needs a only one required argument the font, you can see an example below.
+
+```js
+const fontPath = 'https://raw.githubusercontent.com/Tresjs/assets/main/fonts/FiraCodeRegular.json'
+
+const loader = new FontLoader()
+
+const font = await new Promise((resolve, reject) => {
+  try {
+    loader.load(fontPath, font => {
+      resolve(font)
+    })
+  } catch (error) {
+    reject(console.error('cientos', error))
+  }
+})
+```
+
+Now you can use the `TresTextGeometry` component inside a TresMesh in your scene
+
+```vue
+<template>
+  <TresCanvas shadows alpha>
+    <TresScene>
+      <TresMesh>
+        <TresTextGeometry :args="['TresJS', { font, ...fontOptions }]" center />
+      </TresMesh>
+    </TresScene>
+  </TresCanvas>
+</template>
+```
+
+then as in the example you can pass an object with the desired configurations.
+
+```ts
+const fontOptions = {
+  size: 0.5,
+  height: 0.2,
+  curveSegments: 5,
+  bevelEnabled: true,
+  bevelThickness: 0.05,
+  bevelSize: 0.02,
+  bevelOffset: 0,
+  bevelSegments: 4,
+}
+```
+
+We can also pass a matcapTexture to add final details, using the TresMeshNormalMaterial inside the TresMesh
+
+```ts
+const matcapTexture = await useTexture(['https://raw.githubusercontent.com/Tresjs/assets/main/textures/matcaps/7.png'])
+
+  <TresMesh>
+    <TresTextGeometry :args="['TresJS', { font, ...fontOptions }]" center />
+    <TresMeshNormalMaterial :matcap="matcapTexture" />
+  </TresMesh>
+```
+
+So the final code would be something like this:
+
+```vue
+<script setup lang="ts">
+import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'
+import { FontLoader } from 'three/examples/jsm/loaders/FontLoader'
+import { useCatalogue, useTexture } from '/@/core'
+const { extend } = useCatalogue()
+
+extend({ TextGeometry: TextGeometry })
+
+const fontPath = 'https://raw.githubusercontent.com/Tresjs/assets/main/fonts/FiraCodeRegular.json'
+
+const fontOptions = {
+  size: 0.5,
+  height: 0.2,
+  curveSegments: 5,
+  bevelEnabled: true,
+  bevelThickness: 0.05,
+  bevelSize: 0.02,
+  bevelOffset: 0,
+  bevelSegments: 4,
+}
+
+const loader = new FontLoader()
+
+const font = await new Promise((resolve, reject) => {
+  try {
+    loader.load(fontPath, font => {
+      resolve(font)
+    })
+  } catch (error) {
+    reject(console.error('cientos', error))
+  }
+})
+
+const matcapTexture = await useTexture(['https://raw.githubusercontent.com/Tresjs/assets/main/textures/matcaps/7.png'])
+</script>
+<template>
+  <TresMesh>
+    <TresTextGeometry :args="['TresJS', { font, ...fontOptions }]" center />
+    <TresMeshNormalMaterial :matcap="matcapTexture" />
+  </TresMesh>
+</template>
+```
+
+I know seems like a lot of work, but good news there is a much more simple way
+
+## TextGeometry from `cientos`
+
+The `cientos` package provides a component called `<Text3D />` that is a wrapper of the `TextGeometry` from the [`three-stdlib`](https://github.com/pmndrs/three-stdlib) module.
+
+The nicest part? You don't need to extend the catalog and just pass the font argument.
+It just works. 💯 (if not text is provided, the text will be TresJS)
+
+```vue
+<template>
+  <TresCanvas shadows alpha>
+    <TresScene>
+      <Text3D :font="fontPath" />
+    </TresScene>
+  </TresCanvas>
+</template>
+```
+
+We can pass the options as props
+
+```html
+<Text3D :font="fontPath" :text="my 3d text" :size="0.8" />
+```
+
+in case the options are not provided the default values are:
+
+```js
+size: 0.5,
+height: 0.2,
+curveSegments: 5,
+bevelEnabled: true,
+bevelThickness: 0.05,
+bevelSize: 0.02,
+bevelOffset: 0,
+bevelSegments: 4,
+```
+
+By default text in ThreeJS starts at the mesh initial position, so it's [0,0,0] the text will start there but we can center it by just passing the flag "center"
+
+```js
+<Text3D :font="fontPath" :text="my 3d text" center  />
+```

+ 13 - 1
docs/guide/getting-started.md

@@ -2,10 +2,22 @@
 
 Learn how to install TresJS
 
+::: code-group
+
+```bash [pnpm]
+pnpm add three @tresjs/core -D
 ```
-pnpm i @tresjs/core three
+
+```bash [npm]
+npm install three @tresjs/core -D
 ```
 
+```bash [yarn]
+yarn add three @tresjs/core -D
+```
+
+:::
+
 > Better use with Vue 3.x and composition API
 
 ## Getting started

+ 8 - 7
docs/guide/index.md

@@ -3,22 +3,23 @@
 <ClientOnly>
     <FirstScene style="aspect-ratio: 16/9; height: auto; margin: 2rem 0; border-radius: 8px; overflow:hidden;"/>
 </ClientOnly>
-```
-npm install three @tresjs/core -D
-```
 
-or if you use yarn
+::: code-group
 
+```bash [npm]
+npm install three @tresjs/core -D
 ```
+
+```bash [yarn]
 yarn add three @tresjs/core -D
 ```
 
-pnpm users
-
-```
+```bash [pnpm]
 pnpm add three @tresjs/core -D
 ```
 
+:::
+
 ## Try it online
 
 You can fork this template example on [StackBlitz](https://stackblitz.com/edit/tresjs-basic?file=src/App.vue) and play with it 😋 without installing anything locally.

二進制
docs/public/use-tweakpane.png


+ 5 - 5
package.json

@@ -32,7 +32,7 @@
     "publish:cientos": "pnpm publish --filter @tresjs/cientos",
     "changeset-publish": "changeset publish",
     "changeset-tag": "changeset tag",
-    "changelog": "pnpm run changelog:tres",
+    "changelog": "pnpm run changelog:tres && pnpm run changelog:cientos",
     "changelog:tres": "echo 'generate @tresjs/core changelog' && conventional-changelog -p angular -i ./packages/tres/CHANGELOG.md -s  --commit-path ./packages/tres && git add ./packages/tres/CHANGELOG.md",
     "changelog:cientos": "echo 'generate @tresjs/cientos changelog' && conventional-changelog -p angular -i ./packages/cientos/CHANGELOG.md -s  --commit-path ./packages/cientos && git add ./packages/cientos/CHANGELOG.md",
     "lint": "pnpm run lint:tres && pnpm run lint:cientos",
@@ -51,8 +51,8 @@
     "@changesets/changelog-github": "^0.4.7",
     "@changesets/cli": "^2.25.2",
     "@stackblitz/sdk": "^1.8.1",
-    "@tresjs/cientos": "workspace:^1.1.0",
-    "@tresjs/core": "workspace:^1.2.1",
+    "@tresjs/cientos": "workspace:^1.2.2",
+    "@tresjs/core": "workspace:^1.4.0",
     "@typescript-eslint/eslint-plugin": "^5.42.0",
     "@typescript-eslint/parser": "^5.42.0",
     "conventional-changelog-cli": "^2.2.2",
@@ -60,8 +60,8 @@
     "eslint-config-prettier": "^8.5.0",
     "eslint-plugin-vue": "^9.7.0",
     "prettier": "^2.7.1",
-    "vitepress": "1.0.0-alpha.29",
-    "vue": "^3.2.41",
+    "vitepress": "1.0.0-alpha.33",
+    "vue": "^3.2.45",
     "vue-eslint-parser": "^9.1.0"
   }
 }

+ 23 - 0
packages/cientos/CHANGELOG.md

@@ -1,3 +1,26 @@
+# 1.2.2 (2022-12-19)
+
+### Bug Fixes
+
+- forcing a release with correct bundle versions ([a211e75](https://github.com/Tresjs/tres/commit/a211e758e16bab34d9afaad8496585e1c5b7de3e))
+
+# 1.2.1 (2022-12-19)
+
+### Bug Fixes
+
+- **cientos:** draco encoding and decoderPath ([c9bd7ad](https://github.com/Tresjs/tres/commit/c9bd7ad6ef3ba86855c887886a9032fe0a324dd2))
+
+# 1.2.0 (2022-12-19)
+
+### Bug Fixes
+
+- added copyPublicDir: false to remove static assets on package ([7e8de9c](https://github.com/Tresjs/tres/commit/7e8de9c4b4e63107b79a81a8686ad97256a29017))
+- center props in text3D ([a4e66d3](https://github.com/Tresjs/tres/commit/a4e66d30a015a62ad346e1186f30ea239f7a7bdd))
+
+### Features
+
+- updated deps and clean up app.vue ([88de6eb](https://github.com/Tresjs/tres/commit/88de6eb756967e7f9981bece6bb7105dd9d893d5))
+
 # 1.1.0 (2022-12-08)
 
 ### Bug Fixes

+ 11 - 11
packages/cientos/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@tresjs/cientos",
   "description": "Collection of useful helpers and fully functional, ready-made abstractions for Tres",
-  "version": "1.1.0",
+  "version": "1.2.2",
   "type": "module",
   "author": "Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/)",
   "files": [
@@ -36,25 +36,25 @@
     "lint": "eslint . --ext .js,.jsx,.ts,.tsx,.vue"
   },
   "peerDependencies": {
-    "@tresjs/core": "workspace:^1.2.1",
+    "@tresjs/core": "workspace:^1.4.0",
     "three": "latest",
     "vue": "^3.2.45"
   },
   "devDependencies": {
     "@tweakpane/plugin-essentials": "^0.1.5",
-    "@vitejs/plugin-vue": "^3.2.0",
+    "@vitejs/plugin-vue": "^4.0.0",
     "kolorist": "^1.6.0",
-    "pathe": "^0.3.9",
+    "pathe": "^1.0.0",
     "rollup-plugin-analyzer": "^4.0.0",
     "rollup-plugin-visualizer": "^5.8.3",
-    "tweakpane": "^3.1.0",
-    "typescript": "^4.8.4",
-    "vite": "^3.2.3",
-    "vite-plugin-banner": "^0.6.1",
-    "vite-plugin-dts": "^1.7.0"
+    "tweakpane": "^3.1.1",
+    "typescript": "^4.9.4",
+    "vite": "^4.0.3",
+    "vite-plugin-banner": "^0.7.0",
+    "vite-plugin-dts": "^1.7.1"
   },
   "dependencies": {
-    "@tresjs/core": "workspace:^1.2.1",
-    "three-stdlib": "^2.17.3"
+    "@tresjs/core": "workspace:^1.4.0",
+    "three-stdlib": "^2.21.1"
   }
 }

+ 5 - 3
packages/cientos/src/core/Text3D.vue

@@ -34,7 +34,8 @@ const props = withDefaults(
     bevelThickness?: number
     bevelSize?: number
     bevelOffset?: number
-    bevelSegments?: number
+    bevelSegments?: number,
+    center?: boolean
   }>(),
   {
     size: 0.5,
@@ -45,8 +46,9 @@ const props = withDefaults(
     bevelSize: 0.02,
     bevelOffset: 0,
     bevelSegments: 4,
+    center:false
   },
-)
+  )
 
 const { extend } = useCientos()
 
@@ -92,7 +94,7 @@ const textOptions = computed(() => {
 </script>
 <template>
   <TresMesh v-if="font">
-    <TresTextGeometry v-if="localText" :args="[localText, textOptions]" />
+    <TresTextGeometry v-if="localText" :args="[localText, textOptions]" :center="center" />
     <slot />
   </TresMesh>
 </template>

+ 2 - 1
packages/cientos/src/core/useGLTF/component.ts

@@ -7,12 +7,13 @@ export const GLTFModel = defineComponent({
   props: {
     path: String,
     draco: Boolean,
+    decoderPath: String,
   },
 
   async setup(props) {
     const scene = inject<Ref<Scene>>('local-scene')
 
-    const { scene: model } = await useGLTF(props.path as string, { draco: props.draco })
+    const { scene: model } = await useGLTF(props.path as string, { draco: props.draco, decoderPath: props.decoderPath })
     if (scene?.value) {
       scene.value.add(model)
     }

+ 6 - 3
packages/cientos/src/core/useGLTF/index.ts

@@ -24,10 +24,13 @@ function setExtensions(options: GLTFLoaderOptions, extendLoader?: (loader: GLTFL
     if (extendLoader) {
       extendLoader(loader as GLTFLoader)
     }
-    if (!dracoLoader) {
-      dracoLoader = new DRACOLoader()
+    if (options.draco) {
+      if (!dracoLoader) {
+        dracoLoader = new DRACOLoader()
+      }
+      dracoLoader.setDecoderPath(options.decoderPath || 'https://www.gstatic.com/draco/versioned/decoders/1.4.3/')
+      loader.setDRACOLoader(dracoLoader)
     }
-    dracoLoader.setDecoderPath(options.decoderPath || 'https://www.gstatic.com/draco/versioned/decoders/1.4.3/')
   }
 }
 export async function useGLTF(

+ 10 - 8
packages/cientos/src/core/useTweakPane/index.ts

@@ -8,15 +8,17 @@ let pane: TweakPane
 let fpsGraph: any
 
 export const useTweakPane = (selector = 'tres-container') => {
-  pane = new Pane({
-    container: (document.querySelector(selector) as HTMLElement) || undefined,
-  }) as TweakPane
-  pane.registerPlugin(EssentialsPlugin)
+  if (!pane) {
+    pane = new Pane({
+      container: (document.querySelector(selector) as HTMLElement) || undefined,
+    }) as TweakPane
+    pane.registerPlugin(EssentialsPlugin)
 
-  fpsGraph = pane.addBlade({
-    view: 'fpsgraph',
-    label: 'fpsgraph',
-  })
+    fpsGraph = pane.addBlade({
+      view: 'fpsgraph',
+      label: 'fpsgraph',
+    })
+  }
 
   function disposeTweakPane() {
     if (pane) {

+ 3 - 3
packages/cientos/vite.config.ts

@@ -4,7 +4,7 @@ import { defineConfig } from 'vite'
 import banner from 'vite-plugin-banner'
 import dts from 'vite-plugin-dts'
 import analyze from 'rollup-plugin-analyzer'
-import { visualizer } from 'rollup-plugin-visualizer'
+/* import { visualizer } from 'rollup-plugin-visualizer' */
 
 import { resolve } from 'pathe'
 
@@ -46,11 +46,11 @@ export default defineConfig({
     rollupOptions: {
       plugins: [
         analyze(),
-        visualizer({
+        /* visualizer({
           gzipSize: true,
           brotliSize: true,
           open: false,
-        }),
+        }), */
       ],
       external: ['three', 'vue', '@tresjs/core'],
       output: {

+ 41 - 0
packages/tres/CHANGELOG.md

@@ -1,3 +1,44 @@
+# 1.4.0 (2022-12-22)
+
+### Features
+
+- **core:** added camel keys to set attributes (Support for BufferGeometry) ([fd60380](https://github.com/Tresjs/tres/commit/fd603802a017ee57274542621eb5a21142be9d4a))
+
+## 1.3.3 (2022-12-21)
+
+### Bug Fixes
+
+- **core:** added check for fog ([0a0f7d3](https://github.com/Tresjs/tres/commit/0a0f7d39ace4e3705ec3d8f47ff51bda511ca3e3))
+
+### Features
+
+- **core:** reactive props TresCanvas ([35c8b56](https://github.com/Tresjs/tres/commit/35c8b561c1759cdf584e0e11952f0743e04e5caf))
+
+# 1.3.2 (2022-12-19)
+
+### Bug Fixes
+
+- forcing a release with correct bundle versions ([a211e75](https://github.com/Tresjs/tres/commit/a211e758e16bab34d9afaad8496585e1c5b7de3e))
+
+## 1.3.1 (2022-12-19)
+
+### Bug Fixes
+
+- **cientos:** draco encoding and decoderPath ([c9bd7ad](https://github.com/Tresjs/tres/commit/c9bd7ad6ef3ba86855c887886a9032fe0a324dd2))
+
+# 1.3.0 (2022-12-19)
+
+### Bug Fixes
+
+- added copyPublicDir: false to remove static assets on package ([7e8de9c](https://github.com/Tresjs/tres/commit/7e8de9c4b4e63107b79a81a8686ad97256a29017))
+- center props in text3D ([a4e66d3](https://github.com/Tresjs/tres/commit/a4e66d30a015a62ad346e1186f30ea239f7a7bdd))
+  fcfbce9a03d5ec85ab160b4cc0e99c254b715c1a))
+
+### Features
+
+- docs: updated contributing docs ([d469c90](https://github.com/Tresjs/tres/commit/d469c9004ea7e6702635832e9d5addeba6b6f42d))
+- updated deps and clean up app.vue ([88de6eb](https://github.com/Tresjs/tres/commit/88de6eb756967e7f9981bece6bb7105dd9d893d5))
+
 # 1.2.1 (2022-12-11)
 
 ### Bug Fixes

+ 19 - 17
packages/tres/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@tresjs/core",
   "description": "Declarative ThreeJS using Vue Components",
-  "version": "1.2.1",
+  "version": "1.4.0",
   "type": "module",
   "author": "Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/)",
   "files": [
@@ -40,10 +40,11 @@
     "story:dev": "histoire dev",
     "story:build": "histoire build",
     "story:preview": "histoire preview",
-    "lint": "eslint . --ext .js,.jsx,.ts,.tsx,.vue"
+    "lint": "eslint . --ext .js,.jsx,.ts,.tsx,.vue",
+    "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s"
   },
   "dependencies": {
-    "three": "^0.146.0",
+    "three": "^0.148.0",
     "vue": "^3.2.45"
   },
   "peerDependencies": {
@@ -52,26 +53,27 @@
   "devDependencies": {
     "@alvarosabu/utils": "^2.2.0",
     "@histoire/plugin-vue": "0.11.7",
-    "@tresjs/cientos": "workspace:^1.1.0",
+    "@tresjs/cientos": "workspace:^1.2.2",
     "@types/three": "^0.146.0",
-    "@vitejs/plugin-vue": "^3.2.0",
-    "@vitest/coverage-c8": "^0.25.1",
-    "@vitest/ui": "^0.25.1",
-    "@vueuse/core": "^9.5.0",
+    "@vitejs/plugin-vue": "^4.0.0",
+    "@vitest/coverage-c8": "^0.25.8",
+    "@vitest/ui": "^0.25.8",
+    "@vueuse/core": "^9.7.0",
     "gl": "6.0.1",
-    "happy-dom": "^7.7.0",
-    "histoire": "0.11.7",
+    "happy-dom": "^8.1.0",
+    "histoire": "0.11.9",
     "kolorist": "^1.6.0",
-    "pathe": "^0.3.9",
+    "pathe": "^1.0.0",
+    "release-it": "^15.5.1",
     "rollup-plugin-analyzer": "^4.0.0",
     "rollup-plugin-visualizer": "^5.8.3",
-    "unplugin-vue-components": "^0.22.9",
-    "vite": "^3.2.3",
-    "vite-plugin-banner": "^0.6.1",
-    "vite-plugin-dts": "^1.7.0",
-    "vite-plugin-glsl": "^0.5.3",
+    "unplugin-vue-components": "^0.22.12",
+    "vite": "^4.0.3",
+    "vite-plugin-banner": "^0.7.0",
+    "vite-plugin-dts": "^1.7.1",
+    "vite-plugin-glsl": "^1.0.1",
     "vite-plugin-require-transform": "^1.0.4",
-    "vitest": "^0.25.1",
+    "vitest": "^0.25.8",
     "vue-demi": "^0.13.11"
   }
 }

+ 4 - 24
packages/tres/src/App.vue

@@ -1,32 +1,12 @@
 <script setup lang="ts">
-/* import { useTexture } from '@tresjs/core' */
-import { OrbitControls, Text3D } from '@tresjs/cientos'
+import { useTweakPane } from '@tresjs/cientos'
+import TheExperience from '/@/components/TheExperience.vue'
 
-/* const matcapTexture = await useTexture(['https://raw.githubusercontent.com/Tresjs/assets/main/textures/matcaps/7.png'])
- */
+useTweakPane()
 </script>
 
 <template>
   <Suspense>
-    <TresCanvas
-      clear-color="#82DBC5"
-      shadows
-      alpha
-      window-size
-      power-preference="high-performance"
-      preserve-drawing-buffer
-      physically-correct-lights
-    >
-      <OrbitControls />
-      <TresPerspectiveCamera :position="[5, 5, 5]" :fov="45" :aspect="1" :near="0.1" :far="1000" />
-      <TresScene>
-        <Text3D font="https://raw.githubusercontent.com/Tresjs/assets/main/fonts/FiraCodeRegular.json">
-          TresJS
-          <TresMeshNormalMaterial />
-        </Text3D>
-        <TresAxesHelper :args="[1]" />
-        <TresDirectionalLight :position="[0, 2, 4]" :intensity="2" cast-shadow />
-      </TresScene>
-    </TresCanvas>
+    <TheExperience />
   </Suspense>
 </template>

+ 119 - 0
packages/tres/src/components/TheExperience.vue

@@ -0,0 +1,119 @@
+<script setup lang="ts">
+import {
+  sRGBEncoding,
+  LinearEncoding,
+  BasicShadowMap,
+  PCFShadowMap,
+  PCFSoftShadowMap,
+  VSMShadowMap,
+  NoToneMapping,
+  LinearToneMapping,
+  ReinhardToneMapping,
+  CineonToneMapping,
+  ACESFilmicToneMapping,
+  CustomToneMapping,
+} from 'three'
+import { reactive } from 'vue'
+import { OrbitControls, useTweakPane } from '../../../cientos/src/'
+import { TresCanvas } from '../core/useRenderer/component'
+/* import { OrbitControls, GLTFModel } from '@tresjs/cientos' */
+
+const state = reactive({
+  clearColor: '#201919',
+  shadows: true,
+  alpha: false,
+  physicallyCorrectLights: true,
+  shadowMapType: BasicShadowMap,
+  outputEncoding: sRGBEncoding,
+  toneMapping: NoToneMapping,
+})
+
+const { pane } = useTweakPane()
+
+pane.addInput(state, 'clearColor', {
+  label: 'Background Color',
+  colorMode: 'hex',
+})
+pane.addInput(state, 'shadows', {
+  label: 'Shadows',
+})
+pane.addInput(state, 'physicallyCorrectLights', {
+  label: 'physicallyCorrectLights',
+})
+
+pane
+  .addBlade({
+    view: 'list',
+    label: 'outputEncoding',
+    options: [
+      { text: 'sRGBEncoding', value: sRGBEncoding },
+      { text: 'LinearEncoding', value: LinearEncoding },
+    ],
+    value: sRGBEncoding,
+  })
+  .on('change', ev => {
+    state.outputEncoding = ev.value
+  })
+
+pane
+  .addBlade({
+    view: 'list',
+    label: 'ShadowMap Type',
+    options: [
+      { text: 'BasicShadowMap', value: BasicShadowMap },
+      { text: 'PCFShadowMap', value: PCFShadowMap },
+      { text: 'PCFSoftShadowMap', value: PCFSoftShadowMap },
+      { text: 'VSMShadowMap', value: VSMShadowMap },
+    ],
+    value: BasicShadowMap,
+  })
+  .on('change', ev => {
+    state.shadowMapType = ev.value
+  })
+
+pane
+  .addBlade({
+    view: 'list',
+    label: 'toneMapping',
+    options: [
+      { text: 'NoToneMapping', value: NoToneMapping },
+      { text: 'LinearToneMapping', value: LinearToneMapping },
+      { text: 'ReinhardToneMapping', value: ReinhardToneMapping },
+      { text: 'CineonToneMapping', value: CineonToneMapping },
+      { text: 'ACESFilmicToneMapping', value: ACESFilmicToneMapping },
+      { text: 'CustomToneMapping', value: CustomToneMapping },
+    ],
+    value: NoToneMapping,
+  })
+  .on('change', ev => {
+    console.log(ev.value)
+    state.toneMapping = ev.value
+  })
+</script>
+<template>
+  <TresCanvas v-bind="state">
+    <TresPerspectiveCamera :position="[5, 5, 5]" :fov="45" :near="0.1" :far="1000" :look-at="[-8, 3, -3]" />
+    <TresScene>
+      <OrbitControls />
+      <TresAmbientLight :intensity="0.5" />
+      <TresMesh :position="[-2, 6, 0]" :rotation="[0, Math.PI, 0]" cast-shadow>
+        <TresConeGeometry :args="[1, 1.5, 3]" />
+        <TresMeshToonMaterial color="#82DBC5" />
+      </TresMesh>
+      <TresMesh :position="[0, 4, 0]" cast-shadow>
+        <TresBoxGeometry :args="[1.5, 1.5, 1.5]" />
+        <TresMeshToonMaterial color="#4F4F4F" />
+      </TresMesh>
+      <TresMesh :position="[2, 2, 0]" cast-shadow>
+        <TresSphereGeometry />
+        <TresMeshToonMaterial color="#FBB03B" />
+      </TresMesh>
+      <TresDirectionalLight :position="[0, 8, 4]" :intensity="0.7" cast-shadow />
+      <TresMesh :rotation="[-Math.PI / 2, 0, 0]" receive-shadow>
+        <TresPlaneGeometry :args="[10, 10, 10, 10]" />
+        <TresMeshToonMaterial :color="floorTeal" />
+      </TresMesh>
+      <TresDirectionalLight :position="[0, 2, 4]" :intensity="1" cast-shadow />
+    </TresScene>
+  </TresCanvas>
+</template>

+ 85 - 0
packages/tres/src/components/TheParticles.vue

@@ -0,0 +1,85 @@
+<script setup lang="ts">
+import { reactive } from 'vue'
+import { OrbitControls } from '@tresjs/cientos/src'
+import { TresCanvas } from '../core/useRenderer/component'
+import { AdditiveBlending } from 'three'
+import { useRenderLoop } from '../core/useRenderLoop'
+/* import { OrbitControls, GLTFModel } from '@tresjs/cientos' */
+
+const state = reactive({
+  clearColor: 'teal',
+  shadows: true,
+  alpha: false,
+  physicallyCorrectLights: true,
+})
+
+const shader = {
+  transparent: true,
+  blending: AdditiveBlending,
+  depthWrite: false,
+
+  vertexShader: `
+  uniform float uPixelRatio;
+  uniform float uSize;
+  uniform float uTime;
+  attribute float aScale;
+
+  void main()
+  {
+      vec4 modelPosition = modelMatrix * vec4(position, 1.0);
+      modelPosition.y += sin(uTime + modelPosition.x * 100.0) * aScale * 0.2;
+      vec4 viewPosition = viewMatrix * modelPosition;
+      vec4 projectionPosition = projectionMatrix * viewPosition;
+
+      gl_Position = projectionPosition;
+      gl_PointSize = aScale * uSize * uPixelRatio;
+      gl_PointSize *= (1.0 / - viewPosition.z);
+  }
+  `,
+  fragmentShader: `
+  void main()
+    {
+      float distanceToCenter = distance(gl_PointCoord, vec2(0.5));
+      float strength = 0.05 / distanceToCenter - 0.1;
+
+      gl_FragColor = vec4(1.0, 1.0, 1.0, strength);
+    }
+  `,
+  uniforms: {
+    uSize: { value: 100 },
+    uPixelRatio: { value: Math.min(window.devicePixelRatio, 2) },
+    uTime: { value: 0 },
+  },
+}
+
+const firefliesCount = 30
+const positionArray = new Float32Array(firefliesCount * 3)
+const scaleArray = new Float32Array(firefliesCount)
+
+for (let i = 0; i < firefliesCount; i++) {
+  positionArray[i * 3 + 0] = Math.random() * 4
+  positionArray[i * 3 + 1] = Math.random() * 4
+  positionArray[i * 3 + 2] = Math.random() * 4
+  scaleArray[i] = Math.random()
+}
+
+const { onLoop } = useRenderLoop()
+
+onLoop(({ elapsed }) => {
+  shader.uniforms.uTime.value = elapsed
+})
+</script>
+<template>
+  <TresCanvas v-bind="state">
+    <TresPerspectiveCamera :position="[5, 5, 5]" :fov="45" :near="0.1" :far="1000" :look-at="[-8, 3, -3]" />
+    <TresScene>
+      <OrbitControls />
+      <TresAmbientLight :intensity="0.5" />
+      <TresPoints>
+        <TresBufferGeometry :position="[positionArray, 3]" :a-scale="[scaleArray, 1]" />
+        <TresShaderMaterial v-bind="shader" />
+      </TresPoints>
+      <TresDirectionalLight :position="[0, 2, 4]" :intensity="1" cast-shadow />
+    </TresScene>
+  </TresCanvas>
+</template>

+ 86 - 64
packages/tres/src/core/useInstanceCreator/index.ts

@@ -1,6 +1,6 @@
 /* eslint-disable new-cap */
 /* eslint-disable @typescript-eslint/no-empty-function */
-import { OrthographicCamera, PerspectiveCamera, Scene } from 'three'
+import { BufferAttribute, FogBase, OrthographicCamera, PerspectiveCamera, Scene } from 'three'
 import { defineComponent, inject, Ref } from 'vue'
 import { isArray, isDefined, isFunction } from '@alvarosabu/utils'
 import { normalizeVectorFlexibleParam } from '/@/utils/normalize'
@@ -13,6 +13,16 @@ const VECTOR3_PROPS = ['rotation', 'scale', 'position']
 export function useInstanceCreator(prefix: string) {
   const { logMessage, logError } = useLogger()
 
+  function processSetAttributes(props: Record<string, any>, instance: TresInstance) {
+    if (!isDefined(props)) return
+    if (!isDefined(instance)) return
+
+    Object.entries(props).forEach(([key, value]) => {
+      const camelKey = key.replace(/(-\w)/g, m => m[1].toUpperCase())
+      instance.setAttribute(camelKey, new BufferAttribute(...(value as ConstructorParameters<typeof BufferAttribute>)))
+    })
+  }
+
   function processProps(props: Record<string, any>, instance: TresInstance) {
     if (!isDefined(props)) return
     if (!isDefined(instance)) return
@@ -45,6 +55,7 @@ export function useInstanceCreator(prefix: string) {
 
           // Check if the property is a function
           if (isFunction(instance[camelKey])) {
+            if (key === 'center' && !value) return
             // Call the function with the value, spread if it's an array
             instance[camelKey](...(isArray(value) ? value : [value]))
             return
@@ -90,7 +101,11 @@ export function useInstanceCreator(prefix: string) {
       // check if props is defined on the vnode
       if (vnode?.props) {
         // if props is defined, process the props and pass the internalInstance to update its properties
-        processProps(vnode.props, internalInstance)
+        if (vNodeType === 'BufferGeometry') {
+          processSetAttributes(vnode.props, internalInstance)
+        } else {
+          processProps(vnode.props, internalInstance)
+        }
       }
 
       return internalInstance
@@ -119,72 +134,79 @@ export function useInstanceCreator(prefix: string) {
   }
 
   function createComponentInstances(catalogue: Ref<TresCatalogue>) {
-    return Object.entries(catalogue.value)
-      .filter(([_key, value]) => (value as { prototype: any })?.prototype?.constructor?.toString().includes('class'))
-      .map(([key, threeObj]) => {
-        const name = `${prefix}${key}`
-        const cmp = defineComponent({
-          name,
-          setup(props, { slots, attrs, ...ctx }) {
-            const { scene: fallback } = useScene()
-            const scene = inject<Ref<Scene>>('local-scene') || fallback
-            const catalogue = inject<Ref<TresCatalogue>>('catalogue')
-            const { pushCamera } = useCamera()
-
-            let instance = createInstance(threeObj, attrs, slots)
-            processProps(attrs, instance)
-            // If the instance is a camera, push it to the camera stack
-            if (instance instanceof PerspectiveCamera || instance instanceof OrthographicCamera) {
-              pushCamera(instance)
-            }
-
-            // If the instance is a valid Object3D, add it to the scene
-            if (instance.isObject3D) {
-              scene?.value.add(instance)
-            }
-
-            if (import.meta.hot) {
-              import.meta.hot.on('vite:beforeUpdate', () => {
-                scene.value.remove(instance)
-              })
+    return (
+      Object.entries(catalogue.value)
+        // eslint-disable-next-line @typescript-eslint/no-unused-vars
+        .filter(([_key, value]) => (value as { prototype: any })?.prototype?.constructor?.toString().includes('class'))
+        .map(([key, threeObj]) => {
+          const name = `${prefix}${key}`
+          const cmp = defineComponent({
+            name,
+            setup(props, { slots, attrs, ...ctx }) {
+              const { scene: fallback } = useScene()
+              const scene = inject<Ref<Scene>>('local-scene') || fallback
+              const catalogue = inject<Ref<TresCatalogue>>('catalogue')
+              const { pushCamera } = useCamera()
+
+              let instance = createInstance(threeObj, attrs, slots)
+              processProps(attrs, instance)
+              // If the instance is a camera, push it to the camera stack
+              if (instance instanceof PerspectiveCamera || instance instanceof OrthographicCamera) {
+                pushCamera(instance)
+              }
+
+              // If the instance is a valid Object3D, add it to the scene
+              if (instance.isObject3D) {
+                scene?.value.add(instance)
+              }
+
+              if (scene?.value && instance.isFog) {
+                scene.value.fog = instance as unknown as FogBase
+              }
+
+              if (import.meta.hot) {
+                import.meta.hot.on('vite:beforeUpdate', () => {
+                  scene.value.remove(instance)
+                })
 
-              import.meta.hot.on('vite:afterUpdate', () => {
-                instance = createInstance(threeObj, attrs, slots)
-                processProps(attrs, instance)
-
-                if (instance.isObject3D) {
-                  scene?.value.add(instance)
-                }
-
-                logMessage(name, {
-                  instance,
-                  sceneuuid: scene?.value.uuid,
-                  catalogue: catalogue?.value.uuid,
-                  props,
-                  slots: slots.default ? slots.default() : undefined,
-                  attrs,
-                  ctx,
-                  scene,
+                import.meta.hot.on('vite:afterUpdate', () => {
+                  instance = createInstance(threeObj, attrs, slots)
+                  processProps(attrs, instance)
+
+                  if (instance.isObject3D) {
+                    scene?.value.add(instance)
+                  }
+
+                  logMessage(name, {
+                    instance,
+                    sceneuuid: scene?.value.uuid,
+                    catalogue: catalogue?.value.uuid,
+                    props,
+                    slots: slots.default ? slots.default() : undefined,
+                    attrs,
+                    ctx,
+                    scene,
+                  })
                 })
+              }
+
+              ctx.expose(instance)
+              logMessage(name, {
+                sceneuuid: scene?.value.uuid,
+                catalogue: catalogue?.value.uuid,
+                props,
+                slots: slots.default ? slots.default() : undefined,
+                attrs,
+                ctx,
+                scene,
               })
-            }
-
-            ctx.expose(instance)
-            logMessage(name, {
-              sceneuuid: scene?.value.uuid,
-              catalogue: catalogue?.value.uuid,
-              props,
-              slots: slots.default ? slots.default() : undefined,
-              attrs,
-              ctx,
-              scene,
-            })
-            return () => {}
-          },
-        })
+              return () => {}
+            },
+          })
 
-        return [name, cmp]
-      })
+          return [name, cmp]
+        })
+    )
   }
 
   return {

+ 1 - 1
packages/tres/src/core/useLoader/index.ts

@@ -47,7 +47,7 @@ export async function useLoader<T extends LoaderProto<T>, U extends string | str
   }
 
   if (extensions) {
-    extensions(Loader)
+    extensions(proto)
   }
 
   const paths = (Array.isArray(url) ? url : [url]) as string[]

+ 33 - 34
packages/tres/src/core/useRenderer/index.ts

@@ -1,4 +1,5 @@
-import { watch, ref, shallowRef, computed } from 'vue'
+/* eslint-disable max-len */
+import { watch, ref, shallowRef, computed, toRefs } from 'vue'
 import {
   MaybeComputedRef,
   MaybeElementRef,
@@ -19,6 +20,7 @@ import {
 import type { TextureEncoding, ToneMapping } from 'three'
 import { useRenderLoop, useTres } from '/@/core/'
 import { normalizeColor } from '/@/utils/normalize'
+import { TresColor } from '/@/types'
 
 export interface UseRendererOptions extends WebGLRendererParameters {
   /**
@@ -30,6 +32,8 @@ export interface UseRendererOptions extends WebGLRendererParameters {
 
   /**
    * Set the shadow map type
+   * Can be PCFShadowMap, PCFSoftShadowMap, BasicShadowMap, VSMShadowMap
+   * [see](https://threejs.org/docs/?q=we#api/en/constants/Renderer)
    *
    * @default PCFSoftShadowMap
    */
@@ -45,6 +49,7 @@ export interface UseRendererOptions extends WebGLRendererParameters {
 
   /**
    * Defines the output encoding of the renderer.
+   * Can be LinearEncoding, sRGBEncoding
    *
    * @default LinearEncoding
    */
@@ -52,6 +57,7 @@ export interface UseRendererOptions extends WebGLRendererParameters {
 
   /**
    * Defines the tone mapping used by the renderer.
+   * Can be NoToneMapping, LinearToneMapping, ReinhardToneMapping, Uncharted2ToneMapping, CineonToneMapping, ACESFilmicToneMapping, CustomToneMapping
    *
    * @default NoToneMapping
    */
@@ -91,7 +97,7 @@ export interface UseRendererOptions extends WebGLRendererParameters {
    *
    * @default 0x000000
    */
-  clearColor?: MaybeComputedRef<string | number>
+  clearColor?: MaybeComputedRef<TresColor>
   windowSize?: MaybeComputedRef<boolean>
 }
 
@@ -107,8 +113,8 @@ const isReady = ref(false)
 export function useRenderer(canvas: MaybeElementRef, container: MaybeElementRef, options: UseRendererOptions) {
   // Defaults
   const {
-    alpha = false,
-    antialias,
+    alpha = true,
+    antialias = true,
     depth,
     logarithmicDepthBuffer,
     failIfMajorPerformanceCaveat,
@@ -124,11 +130,11 @@ export function useRenderer(canvas: MaybeElementRef, container: MaybeElementRef,
     context = undefined,
     powerPreference = 'default',
     preserveDrawingBuffer = false,
-    clearColor = normalizeColor('#000000'),
+    clearColor,
     windowSize = false,
-  } = options
+  } = toRefs(options)
 
-  const { width, height } = windowSize ? useWindowSize() : useElementSize(container)
+  const { width, height } = resolveUnref(windowSize) ? useWindowSize() : useElementSize(container)
 
   const { pixelRatio } = useDevicePixelRatio()
   const { pause, resume } = useRenderLoop()
@@ -148,13 +154,14 @@ export function useRenderer(canvas: MaybeElementRef, container: MaybeElementRef,
       return
     }
 
-    renderer.value.shadowMap.enabled = resolveUnref(shadows)
-    renderer.value.outputEncoding = resolveUnref(outputEncoding)
-    renderer.value.shadowMap.type = resolveUnref(shadowMapType)
-    renderer.value.physicallyCorrectLights = resolveUnref(physicallyCorrectLights)
-    renderer.value.toneMapping = resolveUnref(toneMapping)
-    renderer.value.toneMappingExposure = resolveUnref(toneMappingExposure)
-    renderer.value.setClearColor(normalizeColor(resolveUnref(clearColor)))
+    renderer.value.shadowMap.enabled = resolveUnref(shadows) as boolean
+    renderer.value.shadowMap.type = resolveUnref(shadowMapType) as ShadowMapType
+    renderer.value.toneMapping = (resolveUnref(toneMapping) as ToneMapping) || NoToneMapping
+    renderer.value.toneMappingExposure = resolveUnref(toneMappingExposure) as number
+    renderer.value.outputEncoding = (resolveUnref(outputEncoding) as TextureEncoding) || LinearEncoding
+    if (clearColor?.value) renderer.value.setClearColor(normalizeColor(resolveUnref(clearColor) as TresColor))
+
+    renderer.value.physicallyCorrectLights = resolveUnref(physicallyCorrectLights) as boolean
   }
 
   const init = () => {
@@ -166,17 +173,17 @@ export function useRenderer(canvas: MaybeElementRef, container: MaybeElementRef,
 
     renderer.value = new WebGLRenderer({
       canvas: _canvas,
-      alpha,
-      antialias,
-      context,
-      depth,
-      failIfMajorPerformanceCaveat,
-      logarithmicDepthBuffer,
-      powerPreference,
-      precision,
-      stencil,
-      preserveDrawingBuffer,
-      premultipliedAlpha,
+      alpha: resolveUnref(alpha),
+      antialias: resolveUnref(antialias),
+      context: resolveUnref(context),
+      depth: resolveUnref(depth),
+      failIfMajorPerformanceCaveat: resolveUnref(failIfMajorPerformanceCaveat),
+      logarithmicDepthBuffer: resolveUnref(logarithmicDepthBuffer),
+      powerPreference: resolveUnref(powerPreference),
+      precision: resolveUnref(precision),
+      stencil: resolveUnref(stencil),
+      preserveDrawingBuffer: resolveUnref(preserveDrawingBuffer),
+      premultipliedAlpha: resolveUnref(premultipliedAlpha),
     })
 
     const { setState } = useTres()
@@ -203,15 +210,7 @@ export function useRenderer(canvas: MaybeElementRef, container: MaybeElementRef,
 
   watch([width, height, pixelRatio], updateRendererSize)
   watch(
-    () => [
-      shadows,
-      shadowMapType,
-      outputEncoding,
-      physicallyCorrectLights,
-      toneMapping,
-      toneMappingExposure,
-      clearColor,
-    ],
+    [shadows, shadowMapType, outputEncoding, physicallyCorrectLights, toneMapping, toneMappingExposure, clearColor],
     updateRendererOptions,
   )
 

+ 1 - 0
packages/tres/src/types/index.d.ts

@@ -12,6 +12,7 @@ export type TresVNodeType = VNodeTypes & {
 export type TresVNode = VNode & { children?: Array<VNode>; type: TresVNodeType }
 export type TresAttributes = Record<string, any> & { args?: number[] }
 
+export type TresColor = string | number | Color | number[]
 declare global {
   // Define the window interface, with type annotations for the properties and methods of the window object
   interface Window {

+ 3 - 0
packages/tres/src/utils/index.ts

@@ -0,0 +1,3 @@
+export function toSetMethodName(key: string) {
+  return 'set' + key[0].toUpperCase() + key.slice(1)
+}

File diff suppressed because it is too large
+ 572 - 119
pnpm-lock.yaml


Some files were not shown because too many files changed in this diff