فهرست منبع

fix: added logic on pathProps to re-instance nodes once `args` change

alvarosabu 1 سال پیش
والد
کامیت
fef52d96da
2فایلهای تغییر یافته به همراه53 افزوده شده و 2 حذف شده
  1. 9 2
      playground/src/components/DebugUI.vue
  2. 44 0
      src/core/nodeOps.ts

+ 9 - 2
playground/src/components/DebugUI.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
 import { TresCanvas } from '@tresjs/core'
 import { BasicShadowMap, SRGBColorSpace, NoToneMapping } from 'three'
+import { OrbitControls } from '@tresjs/cientos'
 
 // import { OrbitControls, Box } from '@tresjs/cientos'
 /* import { TresLeches, useControls } from '@tresjs/leches' */
@@ -19,13 +20,19 @@ const gl = reactive({
 // useControls(gl)
 // useControls('Box', boxPosition.value)
 
+const boxWidth = ref(1)
+
+setTimeout(() => {
+  boxWidth.value = 2
+}, 2000)
 </script>
 
 <template>
   <TresCanvas v-bind="gl" :window-size="true">
     <TresPerspectiveCamera :look-at="[0, 4, 0]" />
-    <TresMesh :position="[0, 4, 0]">
-      <TresBoxGeometry :args="[1, 1, 1]" />
+    <OrbitControls />
+    <TresMesh :position="[0, 1, 0]">
+      <TresBoxGeometry :args="[boxWidth, 1, 1]" />
       <TresMeshToonMaterial color="teal" />
     </TresMesh>
     <TresGridHelper />

+ 44 - 0
src/core/nodeOps.ts

@@ -15,6 +15,42 @@ function noop(fn: string): any {
   fn
 }
 
+function deepEqual(a, b) {
+  // If both are primitives, return true if they are equal
+  if (a === b) return true;
+
+  // If either of them is null or not an object, return false
+  if (a === null || typeof a !== "object" || b === null || typeof b !== "object") return false;
+
+  // Get the keys of both objects
+  const keysA = Object.keys(a), keysB = Object.keys(b);
+
+  // If they have different number of keys, they are not equal
+  if (keysA.length !== keysB.length) return false;
+
+  // Check each key in A to see if it exists in B and its value is the same in both
+  for (const key of keysA) {
+    if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
+  }
+
+  return true;
+}
+
+function deepArrayEqual(arr1, arr2) {
+  // If they're not both arrays, return false
+  if (!Array.isArray(arr1) || !Array.isArray(arr2)) return false;
+
+  // If they don't have the same length, they're not equal
+  if (arr1.length !== arr2.length) return false;
+
+  // Check each element of arr1 against the corresponding element of arr2
+  for (let i = 0; i < arr1.length; i++) {
+    if (!deepEqual(arr1[i], arr2[i])) return false;
+  }
+
+  return true;
+}
+
 let fallback: TresObject | null = null
 let scene: TresScene | null = null
 
@@ -184,6 +220,14 @@ export const nodeOps: RendererOptions<TresObject, TresObject> = {
       let finalKey = kebabToCamel(key)
       let target = root?.[finalKey]
 
+      if (key === 'args' && !deepArrayEqual(_prevValue, nextValue)) {
+        const prevNode = node as TresObject3D
+
+        if (node.type && nextValue.length > 0) {
+          root = Object.assign(prevNode, new catalogue.value[node.type](...nextValue))
+        }
+      }
+
       if (root.type === 'BufferGeometry') {
         if (key === 'args') return
         root.setAttribute(