瀏覽代碼

chore: refactor instance swaping logic to overwrite set and copy properties

alvarosabu 1 年之前
父節點
當前提交
2df1e651f2
共有 2 個文件被更改,包括 14 次插入10 次删除
  1. 2 1
      playground/src/pages/primitives.vue
  2. 12 9
      src/core/nodeOps.ts

+ 2 - 1
playground/src/pages/primitives.vue

@@ -63,6 +63,8 @@ const sphere = new Mesh(
   }),
 )
 
+sphere.position.set(2, -2, 0)
+
 const firstGroup = new Group()
 firstGroup.add(torus)
 firstGroup.add(torusKnot)
@@ -86,7 +88,6 @@ secondGroup.add(sphere)
     <OrbitControls />
     <primitive
       v-if="isVisible"
-      :position="[4, 2, 0]"
       :object="knot ? firstGroup : sphere"
     />
     <Suspense>

+ 12 - 9
src/core/nodeOps.ts

@@ -191,17 +191,21 @@ export const nodeOps: RendererOptions<TresObject, TresObject> = {
     if (node) {
       let root = node
       let key = prop
-      if ( key === 'object' && prevValue !== null) {
-        const newInstance = nodeOps.createElement('primitive', false, null, { 
+      if (key === 'object' && prevValue !== null) {
+        // If the prop 'object' is changed, we need to re-instance the object and swap the old one with the new one
+        const newInstance = nodeOps.createElement('primitive', undefined, undefined, { 
           object: nextValue, 
         })
-        const blacklistedKeys = ['uuid', 'position', 'rotation', 'scale', 'quaternion']
-        newInstance.uuid = node.uuid
-        for (const key in newInstance) {
-          if (!blacklistedKeys.includes(key)) {
-            node[key] = newInstance[key]
-          }
+        for (const subkey in newInstance) {
+          const target = node[subkey]
+          const value = newInstance[subkey]
+          if (!target?.set && !isFunction(target)) node[subkey] = value
+          else if (target.constructor === value.constructor && target?.copy) target?.copy(value)
+          else if (Array.isArray(value)) target.set(...value)
+          else if (!target.isColor && target.setScalar) target.setScalar(value)
+          else target.set(value)
         }
+        // This code is needed to handle the case where the prop 'object' type change from a group to a mesh or vice versa, otherwise the object will not be rendered correctly (models will be invisible)
         if (newInstance.isGroup) {
           node.geometry = undefined
           node.material = undefined
@@ -209,7 +213,6 @@ export const nodeOps: RendererOptions<TresObject, TresObject> = {
         else {
           delete node.isGroup
         }
-
       }
 
       if (node.isObject3D && key === 'blocks-pointer-events') {