Browse Source

Merge branch 'main' into feature/71-unit-test

alvarosabu 2 years ago
parent
commit
f93021a07c

+ 22 - 0
docs/api/instances-arguments-and-props.md

@@ -89,6 +89,28 @@ All properties whose underlying object has a `.set()` method have a shortcut to
 <TresPerspectiveCamera :position="[1, 2, 3]" />
 <TresPerspectiveCamera :position="[1, 2, 3]" />
 ```
 ```
 
 
+To specify transformation properties such as position, rotation, and scale, a shorthand is available that allows you to directly indicate the axis you wish to set within the props. A similar shorthand is also available for color property.
+
+<!-- I changed color syntax from vue to html, because vue seems broken and does not color nested components -->
+```html
+<TresMesh :position-x="1" :scale-y="2" :rotation-x="Math.PI * 2">
+  <TresMeshBasicMaterial :color-r="0.7" :color-b="0.3" />
+</TresMesh>
+```
+
+::: warning
+When you set the rotation property in [three.js](https://threejs.org/docs/index.html#api/en/math/Euler), it will use the 'XYZ' order by default.
+It is important to note that when setting the rotation property with the shorthand, the order in which you set the angles matters. For more information on this topic, please refer to  [Euler angles](https://en.wikipedia.org/wiki/Euler_angles)
+:::
+
+```vue
+<TresMesh :rotation-x="1" :rotation-y="2" :rotation-z="Math.PI * 2" />
+
+<TresMesh :rotation-z="Math.PI * 2" :rotation-x="1" :rotation-y="2" />
+
+<!-- Note that the order of the rotation properties matters, and swapping the order can result in different outcomes. -->
+```
+
 ### Scalar
 ### Scalar
 
 
 Another shortcut you can use is pass a scalar value to a property that expects a `Vector3` object, using the same value for the rest of the Vector:
 Another shortcut you can use is pass a scalar value to a property that expects a `Vector3` object, using the same value for the rest of the Vector:

+ 2 - 2
docs/guide/index.md

@@ -28,11 +28,11 @@ You can fork this template example on [StackBlitz](https://stackblitz.com/edit/t
 
 
 ## Motivation
 ## Motivation
 
 
-[ThreeJS](https://threejs.org/) is a wonderfull library to create awesome **WebGL** 3D websites. Is also a constantly updated library that makes hard for wrapper mantainers like [TroisJS](https://troisjs.github.io/) to keep up with all the enhancements.
+[ThreeJS](https://threejs.org/) is a wonderful library to create awesome **WebGL** 3D websites. Is also a constantly updated library that makes hard for wrapper maintainers like [TroisJS](https://troisjs.github.io/) to keep up with all the enhancements.
 
 
 React ecosystem has an impresive **custom render** solution called [React-three-fiber](https://docs.pmnd.rs/react-three-fiber) that allows you build your scenes declaratively with re-usable, self-contained components that react to state.
 React ecosystem has an impresive **custom render** solution called [React-three-fiber](https://docs.pmnd.rs/react-three-fiber) that allows you build your scenes declaratively with re-usable, self-contained components that react to state.
 
 
-In my search for something similar in the VueJS ecosystem, I found this amazing library called [Lunchbox](https://github.com/breakfast-studio/lunchboxjs) which works with the same concept that R3F, it provides a [custom Vue3 Renderer](https://vuejs.org/api/custom-renderer.html). I'm also contrubuiting to improve this library so it gets as mature and feature-rich as R3F.
+In my search for something similar in the VueJS ecosystem, I found this amazing library called [Lunchbox](https://github.com/breakfast-studio/lunchboxjs) which works with the same concept that R3F, it provides a [custom Vue3 Renderer](https://vuejs.org/api/custom-renderer.html). I'm also contributing to improve this library so it gets as mature and feature-rich as R3F.
 
 
 The only problem is, mixing different renderers in Vue 3 is something the Vue community is still working on - see [here](https://github.com/vuejs/vue-loader/pull/1645) for more information.
 The only problem is, mixing different renderers in Vue 3 is something the Vue community is still working on - see [here](https://github.com/vuejs/vue-loader/pull/1645) for more information.
 
 

+ 1 - 0
packages/tres/src/App.vue

@@ -5,5 +5,6 @@ import TheEnvironment from '/@/components/TheEnvironment.vue'
 <template>
 <template>
   <Suspense>
   <Suspense>
     <TheEnvironment />
     <TheEnvironment />
+    <!-- <VectorSetProps /> -->
   </Suspense>
   </Suspense>
 </template>
 </template>

+ 70 - 0
packages/tres/src/components/VectorSetProps.vue

@@ -0,0 +1,70 @@
+<script setup lang="ts">
+import { sRGBEncoding, BasicShadowMap, NoToneMapping } from 'three'
+import { reactive } from 'vue'
+
+import { OrbitControls } from '@tresjs/cientos'
+// import { useRenderLoop } from '..'
+/* import { OrbitControls, GLTFModel } from '@tresjs/cientos' */
+
+const state = reactive({
+  clearColor: '#201919',
+  shadows: true,
+  alpha: false,
+  physicallyCorrectLights: true,
+  shadowMapType: BasicShadowMap,
+  outputEncoding: sRGBEncoding,
+  toneMapping: NoToneMapping,
+})
+</script>
+<template>
+  <TresCanvas v-bind="state">
+    <TresPerspectiveCamera
+      :position-x="5"
+      :position-y="5"
+      :position-z="5"
+      :fov="45"
+      :near="0.1"
+      :far="1000"
+      :look-at="[-8, 3, -3]"
+    />
+    <OrbitControls make-default />
+    <TresScene>
+      <TresAmbientLight :intensity="0.5" />
+
+      <TresMesh
+        :scale-x="1.1"
+        :scale-y="2"
+        :scale-z="3"
+        :rotation-x="Math.PI * 1.5"
+        :rotation-y="Math.PI * 0.6"
+        :rotation-z="Math.PI * 0.2"
+        :position-y="1"
+        :position-z="-2"
+        cast-shadow
+      >
+        <TresBoxGeometry />
+        <TresMeshToonMaterial color="#FBB03B" />
+      </TresMesh>
+      <TresMesh
+        :scale-x="1.1"
+        :scale-y="2"
+        :scale-z="3"
+        :rotation-y="Math.PI * 0.6"
+        :rotation-x="Math.PI * 1.5"
+        :rotation-z="Math.PI * 0.2"
+        :position-y="1"
+        :position-z="2"
+        cast-shadow
+      >
+        <TresBoxGeometry />
+        <TresMeshToonMaterial :color-r="0xff / 255" :color-g="0x0 / 255" :color-b="0xff / 255" />
+      </TresMesh>
+      <TresDirectionalLight :position-y="8" :position-z="4" :intensity="0.7" cast-shadow />
+      <TresMesh :rotation="[-Math.PI / 2, 0, 0]" receive-shadow>
+        <TresPlaneGeometry :args="[10, 10, 10, 10]" />
+        <TresMeshToonMaterial />
+      </TresMesh>
+      <TresDirectionalLight :position-y="2" :position-z="4" :intensity="1" cast-shadow />
+    </TresScene>
+  </TresCanvas>
+</template>

+ 53 - 1
packages/tres/src/core/useInstanceCreator/index.ts

@@ -11,6 +11,9 @@ import { useLogger } from '/@/composables'
 import { TresAttributes, TresCatalogue, TresInstance, TresVNode, TresVNodeType, TresEvent } from '/@/types'
 import { TresAttributes, TresCatalogue, TresInstance, TresVNode, TresVNodeType, TresEvent } from '/@/types'
 
 
 const VECTOR3_PROPS = ['rotation', 'scale', 'position']
 const VECTOR3_PROPS = ['rotation', 'scale', 'position']
+const VECTOR3_AXIS = ['X', 'Y', 'Z']
+const COLOR_PROPS = ['color']
+const COLOR_KEYS = ['r', 'g', 'b']
 
 
 /**
 /**
  * Composable responsible for creating instances out of Three.js objects.
  * Composable responsible for creating instances out of Three.js objects.
@@ -57,14 +60,43 @@ export function useInstanceCreator(prefix: string) {
 
 
     Object.entries(props).forEach(([key, value]) => {
     Object.entries(props).forEach(([key, value]) => {
       const camelKey = key.replace(/(-\w)/g, m => m[1].toUpperCase())
       const camelKey = key.replace(/(-\w)/g, m => m[1].toUpperCase())
-
+      let transformProps
+      let transformAxis
+      let colorProps
+      let colorKey
       // Ignore property args which is use for initial instance construction
       // Ignore property args which is use for initial instance construction
       if (camelKey === 'args' || value === undefined) return
       if (camelKey === 'args' || value === undefined) return
 
 
       // Normalize vector3 props
       // Normalize vector3 props
       if (VECTOR3_PROPS.includes(camelKey) && value) {
       if (VECTOR3_PROPS.includes(camelKey) && value) {
         value = normalizeVectorFlexibleParam(value)
         value = normalizeVectorFlexibleParam(value)
+      } else {
+        VECTOR3_PROPS.forEach(vecProps => {
+          // Check if the props starts with one of the transform props
+          // and is followed only with one of the axis
+          if (camelKey.startsWith(vecProps) && camelKey.length === vecProps.length + 1) {
+            transformProps = vecProps
+            transformAxis = camelKey.substring(vecProps.length)
+            if (!VECTOR3_AXIS.includes(transformAxis)) {
+              logError(
+                `There was an error setting ${key} property`,
+                `${transformAxis} is not a valid axis for ${transformProps}`,
+              )
+            }
+          }
+        })
       }
       }
+      COLOR_PROPS.forEach(props => {
+        // Check if the props starts with one of the color props
+        // and is followed only with one of the key
+        if (camelKey.startsWith(props) && camelKey.length === props.length + 1) {
+          colorProps = props
+          colorKey = camelKey.substring(props.length).toLowerCase()
+          if (!COLOR_KEYS.includes(colorKey)) {
+            logError(`There was an error setting ${key} property`, `${colorKey} is not a valid axis for ${colorProps}`)
+          }
+        }
+      })
 
 
       if (props.ref) {
       if (props.ref) {
         props.ref = instance
         props.ref = instance
@@ -75,6 +107,26 @@ export function useInstanceCreator(prefix: string) {
         if (instance[camelKey] && isDefined(instance[camelKey].set)) {
         if (instance[camelKey] && isDefined(instance[camelKey].set)) {
           // Call the "set" method with the value, spread if it's an array
           // Call the "set" method with the value, spread if it's an array
           instance[camelKey].set(...(isArray(value) ? value : [value]))
           instance[camelKey].set(...(isArray(value) ? value : [value]))
+        } else if (
+          // Check if the property has a "setAxis" method
+          transformProps &&
+          instance[transformProps]
+        ) {
+          // Check if setAxis function exist
+          // if it doesn't check if props is rotation
+          if (isDefined(instance[transformProps][`set${transformAxis}`])) {
+            instance[transformProps][`set${transformAxis}`](value)
+          } else if (isDefined(instance[`rotate${transformAxis}`])) {
+            instance[`rotate${transformAxis}`](value)
+          }
+        } else if (
+          // Check if the instance has a "color" property
+          colorProps &&
+          colorKey &&
+          instance[colorProps] &&
+          instance[colorProps][colorKey]
+        ) {
+          instance[colorProps][colorKey] = value
         } else {
         } else {
           // Convert empty strings to `true`
           // Convert empty strings to `true`
           if (value === '') {
           if (value === '') {