|
1 | 1 | import {
|
2 |
| - afterNextRender, |
3 | 2 | ChangeDetectionStrategy,
|
4 | 3 | Component,
|
5 | 4 | computed,
|
6 | 5 | CUSTOM_ELEMENTS_SCHEMA,
|
7 | 6 | effect,
|
8 | 7 | ElementRef,
|
9 |
| - inject, |
10 | 8 | Injector,
|
11 | 9 | input,
|
12 | 10 | viewChild,
|
@@ -178,43 +176,40 @@ export class NgtsSampler {
|
178 | 176 | options = input(defaultOptions, { transform: mergeInputs(defaultOptions) });
|
179 | 177 | parameters = omit(this.options, ['weight', 'transform', 'count']);
|
180 | 178 |
|
181 |
| - groupRef = viewChild.required<ElementRef<Group>>('group'); |
182 |
| - |
183 |
| - private sampleState = computed(() => { |
184 |
| - const group = this.groupRef().nativeElement; |
185 |
| - const localState = getLocalState(group); |
186 |
| - if (!localState) return { mesh: null, instanced: null }; |
187 |
| - |
188 |
| - const [mesh, instances] = [resolveRef(this.mesh()), resolveRef(this.instances())]; |
189 |
| - const objects = localState.objects(); |
190 |
| - |
191 |
| - return { |
192 |
| - mesh: mesh ?? (objects.find((c) => c.type === 'Mesh') as Mesh), |
193 |
| - instanced: |
194 |
| - instances ?? (objects.find((c) => !!Object.getOwnPropertyDescriptor(c, 'instanceMatrix')) as InstancedMesh), |
195 |
| - }; |
196 |
| - }); |
| 179 | + // NOTE: this could have been a viewChild.required, but we need to _try_ to consume |
| 180 | + // this Signal earlier than when a viewChild.required would resolve. |
| 181 | + groupRef = viewChild<ElementRef<Group>>('group'); |
197 | 182 |
|
198 | 183 | constructor() {
|
199 | 184 | extend({ Group });
|
200 |
| - const injector = inject(Injector); |
201 |
| - |
202 |
| - afterNextRender(() => { |
203 |
| - const meshToSample = pick(this.sampleState, 'mesh'); |
204 |
| - const instancedToSample = pick(this.sampleState, 'instanced'); |
205 |
| - |
206 |
| - const sampler = injectSurfaceSampler( |
207 |
| - meshToSample, |
208 |
| - () => ({ |
209 |
| - count: this.options().count, |
210 |
| - transform: this.options().transform, |
211 |
| - weight: this.options().weight, |
212 |
| - instanceMesh: instancedToSample(), |
213 |
| - }), |
214 |
| - { injector }, |
215 |
| - ); |
216 | 185 |
|
217 |
| - effect(sampler, { injector }); |
| 186 | + const sampleState = computed(() => { |
| 187 | + const group = this.groupRef()?.nativeElement; |
| 188 | + const localState = getLocalState(group); |
| 189 | + if (!localState) return { mesh: null, instanced: null }; |
| 190 | + |
| 191 | + const [mesh, instances] = [resolveRef(this.mesh()), resolveRef(this.instances())]; |
| 192 | + const objects = localState.objects(); |
| 193 | + |
| 194 | + return { |
| 195 | + mesh: mesh ?? (objects.find((c) => c.type === 'Mesh') as Mesh), |
| 196 | + instanced: |
| 197 | + instances ?? (objects.find((c) => !!Object.getOwnPropertyDescriptor(c, 'instanceMatrix')) as InstancedMesh), |
| 198 | + }; |
218 | 199 | });
|
| 200 | + |
| 201 | + const meshToSample = pick(sampleState, 'mesh'); |
| 202 | + const instancedToSample = pick(sampleState, 'instanced'); |
| 203 | + |
| 204 | + // NOTE: because injectSurfaceSampler returns a computed, we need to consume |
| 205 | + // this computed in a Reactive Context (an effect) to ensure the inner logic of |
| 206 | + // injectSurfaceSampler is run properly. |
| 207 | + const sampler = injectSurfaceSampler(meshToSample, () => ({ |
| 208 | + count: this.options().count, |
| 209 | + transform: this.options().transform, |
| 210 | + weight: this.options().weight, |
| 211 | + instanceMesh: instancedToSample(), |
| 212 | + })); |
| 213 | + effect(sampler); |
219 | 214 | }
|
220 | 215 | }
|
0 commit comments