Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions playground/src/components/DebugUI.vue
Original file line number Diff line number Diff line change
@@ -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' */
Expand All @@ -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 />
Expand Down
10 changes: 9 additions & 1 deletion src/core/nodeOps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { BufferAttribute } from 'three'
import { isFunction } from '@alvarosabu/utils'
import { useLogger } from '../composables'
import { catalogue } from './catalogue'
import { isHTMLTag, kebabToCamel } from '../utils'
import { deepArrayEqual, isHTMLTag, kebabToCamel } from '../utils'

import type { Object3D, Camera } from 'three'
import type { TresObject, TresObject3D, TresScene } from '../types'
Expand Down Expand Up @@ -184,6 +184,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))
}
}

alvarosabu marked this conversation as resolved.
Show resolved Hide resolved
if (root.type === 'BufferGeometry') {
if (key === 'args') return
root.setAttribute(
Expand Down
39 changes: 38 additions & 1 deletion src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,41 @@ export const set = (obj: any, path: string | string[], value: any): void => {
if (i === pathArray.length - 1) acc[key] = value;
return acc[key];
}, obj);
};
};


export function deepEqual(a: any, b: any): boolean {
// 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;
}

export function deepArrayEqual(arr1: any[], arr2: any[]): boolean {
// 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;
}