Quellcode durchsuchen

fix: avoid pierced props to setScalar when numerical (#1073)

* fix: avoid pierced props to setScalar when numerical

- Fixed `nodeOps` to directly assign pierced props with number values, ensuring proper handling of vector properties and added tests for verifying the integrity of node operations.
- Improved test coverage for `patchProp` to ensure that properties remain unchanged when not explicitly modified.

* refactor: clean up comments in nodeOps

- Removed redundant comments in `nodeOps` regarding the handling of pierced props with number values, streamlining the code for better readability while maintaining functionality.
Alvaro Saburido vor 1 Monat
Ursprung
Commit
4e7ba85d28

+ 2 - 6
playground/vue/src/pages/basic/PiercedProps.vue

@@ -3,7 +3,6 @@ import { TresCanvas } from '@tresjs/core'
 import { TresLeches } from '@tresjs/leches'
 import '@tresjs/leches/styles'
 import { shallowRef } from 'vue'
-import LocalOrbitControls from '../../components/LocalOrbitControls.vue'
 
 const x = shallowRef(1)
 const y = shallowRef(1)
@@ -34,10 +33,6 @@ const onLoop = ({ elapsed }: { elapsed: number }) => {
   refs[i].value = Math.cos(elapsed * Math.PI * 2)
   label.value = `${labels[i]} ${Math.trunc(refs[i].value * 10) / 10}`
 }
-
-// const { enableZoom } = useControls({
-//   enableZoom: false,
-// })
 </script>
 
 <template>
@@ -47,6 +42,7 @@ const onLoop = ({ elapsed }: { elapsed: number }) => {
   </div>
   <TresLeches />
   <TresCanvas @loop="onLoop">
+    <TresPerspectiveCamera :position="[5, 5, 5]" :look-at="[0, 0, 0]" />
     <TresMesh
       :position-x="x"
       :position-y="y"
@@ -61,7 +57,7 @@ const onLoop = ({ elapsed }: { elapsed: number }) => {
       <TresBoxGeometry />
       <TresMeshNormalMaterial />
     </TresMesh>
-    <LocalOrbitControls :enable-zoom="enableZoom" />
+    <TresGridHelper :size="10" :divisions="10" />
   </TresCanvas>
 </template>
 

+ 2 - 1
playground/vue/src/pages/basic/index.vue

@@ -59,7 +59,7 @@ const formattedShadowMapType = computed(() => {
   >
     <TresPerspectiveCamera :position="[5, 5, 5]" :look-at="[0, 0, 0]" />
     <OrbitControls />
-    <TresMesh :position="[0, 1, 0]" cast-shadow>
+    <TresMesh cast-shadow :position-x="2">
       <TresBoxGeometry />
       <TresMeshStandardMaterial color="teal" :opacity="0.5" transparent />
     </TresMesh>
@@ -71,6 +71,7 @@ const formattedShadowMapType = computed(() => {
       <TresPlaneGeometry :args="[10, 10, 10, 10]" />
       <TresMeshToonMaterial />
     </TresMesh>
+    <TresAxesHelper />
     <!-- Add lighting to see the edges better -->
     <TresDirectionalLight :position="[1, 1, -1]" cast-shadow :intensity="2" />
     <TresAmbientLight :intensity="1" />

+ 24 - 1
src/core/nodeOps.test.ts

@@ -1047,12 +1047,35 @@ describe('nodeOps', () => {
       const node = nodeOps.createElement('Mesh')!
       const prop = 'position-x'
       const nextValue = 5
+      const originalY = node.position.y
+      const originalZ = node.position.z
 
       // Test
       nodeOps.patchProp(node, prop, null, nextValue)
 
       // Assert
-      expect(node.position.x === nextValue)
+      expect(node.position.x).toBe(nextValue)
+      expect(node.position.y).toBe(originalY) // Should remain unchanged
+      expect(node.position.z).toBe(originalZ) // Should remain unchanged
+    })
+
+    it('patches/traverses pierced props with array values', async () => {
+    // Setup
+      const light = nodeOps.createElement('DirectionalLight')!
+
+      // DirectionalLight shadow might be null by default, need to enable it
+      light.castShadow = true // This should initialize the shadow
+
+      const prop = 'shadow-mapSize'
+      const nextValue = [2048, 2048]
+
+      // Test
+      nodeOps.patchProp(light, prop, null, nextValue)
+
+      // Assert
+      expect(light.shadow).toBeTruthy()
+      expect(light.shadow.mapSize[0]).toBe(2048)
+      expect(light.shadow.mapSize[1]).toBe(2048)
     })
 
     it('does not patch/traverse pierced props of existing dashed properties', async () => {

+ 9 - 0
src/core/nodeOps.ts

@@ -302,6 +302,15 @@ export const nodeOps: (context: TresContext) => RendererOptions<TresObject, Tres
       target = resolved.target
       root = resolved.target
       finalKey = resolved.key
+
+      if (target && finalKey) {
+        target[finalKey] = nextValue
+        if (isTresCamera(node)) {
+          node.updateProjectionMatrix()
+        }
+        invalidateInstance(node as TresObject)
+        return
+      }
     }
     let value = nextValue
     if (value === '') { value = true }