Skip to content

Commit 2cf9113

Browse files
committed
fix(core): add geometryStamp to ngt instance
A new `geometryStamp` is added to `ngt.instanceStore`. This allows the renderer to update the Local State when a geometry is applied via `setProperty`. When this is the case, normal `nonObjects()` will not work because the geometry isn't added via content of the parent. However, we still need to track / rerun effects on geometries' changes most of the times. This allows us to notify the Local State when the geometry property is updated (via `[geometry]`) A new `nonObjectsChanged` computed is a combination of `nonObjects()` and `geometryStamp()`. Consumers using `localState.nonObjects()` will automatically get the changes from `geometryStamp` as well.
1 parent 86d31aa commit 2cf9113

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

libs/core/src/lib/instance.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { computed } from '@angular/core';
12
import { NgtAnyRecord, NgtInstanceNode, NgtLocalInstanceState, NgtLocalState } from './types';
23
import { signalStore } from './utils/signal-store';
34
import { checkUpdate } from './utils/update';
@@ -34,10 +35,19 @@ export function prepare<TInstance extends object = NgtAnyRecord>(
3435
parent: null,
3536
objects: [],
3637
nonObjects: [],
38+
geometryStamp: Date.now(),
3739
}),
3840
...rest
3941
} = localState || {};
4042

43+
const nonObjects = instanceStore.select('nonObjects');
44+
const geometryStamp = instanceStore.select('geometryStamp');
45+
46+
const nonObjectsChanged = computed(() => {
47+
const [_nonObjects] = [nonObjects(), geometryStamp()];
48+
return _nonObjects;
49+
});
50+
4151
instance.__ngt__ = {
4252
previousAttach: null,
4353
store: null,
@@ -47,7 +57,7 @@ export function prepare<TInstance extends object = NgtAnyRecord>(
4757
instanceStore,
4858
parent: instanceStore.select('parent'),
4959
objects: instanceStore.select('objects'),
50-
nonObjects: instanceStore.select('nonObjects'),
60+
nonObjects: nonObjectsChanged,
5161
add(object, type) {
5262
const current = instance.__ngt__.instanceStore.snapshot[type];
5363
const foundIndex = current.indexOf((node: NgtInstanceNode) => object === node);
@@ -68,6 +78,9 @@ export function prepare<TInstance extends object = NgtAnyRecord>(
6878
setParent(parent) {
6979
instance.__ngt__.instanceStore.update({ parent });
7080
},
81+
updateGeometryStamp() {
82+
instance.__ngt__.instanceStore.update({ geometryStamp: Date.now() });
83+
},
7184
...rest,
7285
} as NgtLocalState;
7386
}

libs/core/src/lib/renderer/index.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,17 +429,23 @@ export class NgtRenderer implements Renderer2 {
429429
const rS = el.__ngt_renderer__;
430430
if (!rS || rS[NgtRendererClassId.destroyed]) return;
431431

432+
const localState = getLocalState(el);
433+
432434
if (rS[NgtRendererClassId.type] === 'three') {
433435
if (name === SPECIAL_PROPERTIES.PARAMETERS) {
434436
// NOTE: short-cut for null raycast to prevent upstream from creating a nullRaycast property
435437
if ('raycast' in value && value['raycast'] === null) {
436438
value['raycast'] = () => null;
437439
}
438440
applyProps(el, value);
441+
442+
if ('geometry' in value && value['geometry'].isBufferGeometry) {
443+
localState?.updateGeometryStamp();
444+
}
445+
439446
return;
440447
}
441448

442-
const localState = getLocalState(el);
443449
const parent = localState?.instanceStore.get('parent') || rS[NgtRendererClassId.parent];
444450

445451
// [rawValue]
@@ -469,6 +475,11 @@ export class NgtRenderer implements Renderer2 {
469475
}
470476

471477
applyProps(el, { [name]: value });
478+
479+
if (name === 'geometry' && value.isBufferGeometry) {
480+
localState?.updateGeometryStamp();
481+
}
482+
472483
return;
473484
}
474485

0 commit comments

Comments
 (0)