1
0
Эх сурвалжийг харах

Merge branch 'main' into feature/67-usefbx-composable-and-component-for-cientos

Alvaro 2 жил өмнө
parent
commit
bb315e05fa

+ 1 - 0
docs/.vitepress/config.ts

@@ -39,6 +39,7 @@ export default defineConfig({
         items: [
           { text: 'Orbit Controls', link: '/examples/orbit-controls' },
           { text: 'Basic Animations', link: '/examples/basic-animations' },
+          { text: 'Groups', link: '/examples/groups' },
           { text: 'Load Textures', link: '/examples/load-textures' },
           { text: 'Load Models', link: '/examples/load-models' },
           { text: 'Load Text', link: '/examples/text-3d' },

+ 32 - 0
docs/examples/groups.md

@@ -0,0 +1,32 @@
+# Group <Badge type="warning" text="^1.5.0" />
+
+A `<TresGroup>` is an instance of the [THREE.Group](https://threejs.org/docs/#api/en/objects/Group) class which is almost the same as a [THREE.Object3D](https://threejs.org/docs/#api/en/objects/Object3D) but allows you to **group together multiple objects in the scene** so that they can be manipulated as a single unit (transform, rotation, etc).
+
+<StackBlitzEmbed projectId="tresjs-groups" />
+
+## Usage
+
+```vue{12,21}
+<script setup lang="ts">
+const groupRef = ref()
+const { onLoop } = useRenderLoop()
+
+onLoop(() => {
+  if (groupRef.value) {
+    groupRef.value.rotation.y += 0.01
+  }
+})
+</script>
+<template>
+  <TresGroup ref="groupRef" :position="[2,0,0]">
+    <TresMesh>
+      <TresBoxGeometry />
+      <TresMeshBasicMaterial color="red" />
+    </TresMesh>
+    <TresMesh>
+      <TresSphereGeometry />
+      <TresMeshBasicMaterial color="blue" />
+    </TresMesh>
+  </TresGroup>
+</template>
+```

+ 2 - 2
packages/tres/src/App.vue

@@ -1,12 +1,12 @@
 <script setup lang="ts">
 import { useTweakPane } from '@tresjs/cientos'
-import TheExperience from '/@/components/TheExperience.vue'
+import TheGroups from '/@/components/TheGroups.vue'
 
 useTweakPane()
 </script>
 
 <template>
   <Suspense>
-    <TheExperience />
+    <TheGroups />
   </Suspense>
 </template>

+ 37 - 0
packages/tres/src/components/TheGroups.vue

@@ -0,0 +1,37 @@
+<script setup lang="ts">
+import { useRenderLoop } from '/@/core/useRenderLoop'
+import { ref } from 'vue'
+import { OrbitControls } from '../../../cientos/src/'
+
+const { onLoop } = useRenderLoop()
+
+const groupRef = ref()
+
+onLoop(() => {
+  if (groupRef.value) {
+    groupRef.value.rotation.y += 0.01
+  }
+})
+</script>
+<template>
+  <div class="container">
+    <TresCanvas>
+      <TresPerspectiveCamera :position="[5, 5, 5]" :fov="75" :aspect="1" :near="0.1" :far="1000" />
+      <OrbitControls />
+      <TresScene>
+        <TresAmbientLight :color="0xffffff" :intensity="0.5" />
+        <TresGroup ref="groupRef" :position="[0, -4, -5]">
+          <TresMesh :scale="1" :position="[-4, 0, 0]" cast-shadow>
+            <TresSphereGeometry :args="[1, 500, 500]" />
+            <TresMeshToonMaterial color="#FBB03B" />
+          </TresMesh>
+          <TresMesh :scale="1" :position="[4, 0, 0]" cast-shadow>
+            <TresSphereGeometry :args="[1, 500, 500]" />
+            <TresMeshToonMaterial color="teal" />
+          </TresMesh>
+        </TresGroup>
+        <TresAxesHelper />
+      </TresScene>
+    </TresCanvas>
+  </div>
+</template>

+ 18 - 3
packages/tres/src/core/useInstanceCreator/index.ts

@@ -82,10 +82,17 @@ export function useInstanceCreator(prefix: string) {
       const vNodeType = ((vnode.type as TresVNodeType).name as string).replace(prefix, '')
       const { catalogue: fallback } = useCatalogue()
       const catalogue = inject<Ref<TresCatalogue>>('catalogue') || fallback
+
       // check if args prop is defined on the vnode
       let internalInstance
       if (catalogue) {
-        if (vnode?.props?.args) {
+        if (vnode.children?.default) {
+          const internal = vnode.children
+            .default()
+            .map(child => createInstanceFromVNode(child as TresVNode)) as TresInstance[]
+
+          internalInstance = new catalogue.value[vNodeType](...internal.flat().filter(Boolean))
+        } else if (vnode?.props?.args) {
           // if args prop is defined, create new instance of catalogue[vNodeType] with the provided arguments
           if (catalogue?.value[vNodeType]) {
             internalInstance = new catalogue.value[vNodeType](...vnode.props.args)
@@ -107,7 +114,7 @@ export function useInstanceCreator(prefix: string) {
           processProps(vnode.props, internalInstance)
         }
       }
-
+      logMessage(`Created ${vNodeType} instance`, internalInstance)
       return internalInstance
     }
   }
@@ -126,7 +133,15 @@ export function useInstanceCreator(prefix: string) {
      */
     if (slots.default && slots?.default()) {
       const internal = slots.default().map((vnode: TresVNode) => createInstanceFromVNode(vnode))
-      return new threeObj(...internal.flat().filter(Boolean))
+      if (threeObj.name === 'Group') {
+        const group = new threeObj()
+        internal.forEach((child: TresInstance) => {
+          group.add(child)
+        })
+        return group
+      } else {
+        return new threeObj(...internal.flat().filter(Boolean))
+      }
     } else {
       // Creates a new THREE instance, if args is present, spread it on the constructor
       return attrs.args ? new threeObj(...attrs.args) : new threeObj()

+ 3 - 0
packages/tres/vite.config.ts

@@ -18,6 +18,9 @@ import pkg from './package.json'
 console.log(`${lightGreen('▲')} ${gray('■')} ${yellow('●')} ${bold('Tres')} v${pkg.version}`)
 // https://vitejs.dev/config/
 export default defineConfig({
+  server: {
+    port: 5174,
+  },
   resolve: {
     alias: {
       '/@': resolve(__dirname, './src'),