@pascal-app/viewer 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/components/renderers/ceiling/ceiling-renderer.d.ts.map +1 -1
  2. package/dist/components/renderers/ceiling/ceiling-renderer.js +4 -3
  3. package/dist/components/renderers/door/door-renderer.d.ts.map +1 -1
  4. package/dist/components/renderers/door/door-renderer.js +5 -2
  5. package/dist/components/renderers/fence/fence-renderer.d.ts.map +1 -1
  6. package/dist/components/renderers/fence/fence-renderer.js +16 -2
  7. package/dist/components/renderers/roof/roof-renderer.d.ts.map +1 -1
  8. package/dist/components/renderers/roof/roof-renderer.js +31 -9
  9. package/dist/components/renderers/roof-segment/roof-segment-renderer.d.ts.map +1 -1
  10. package/dist/components/renderers/roof-segment/roof-segment-renderer.js +42 -8
  11. package/dist/components/renderers/site/site-renderer.d.ts.map +1 -1
  12. package/dist/components/renderers/site/site-renderer.js +7 -1
  13. package/dist/components/renderers/slab/slab-renderer.d.ts.map +1 -1
  14. package/dist/components/renderers/slab/slab-renderer.js +37 -8
  15. package/dist/components/renderers/stair/stair-renderer.d.ts.map +1 -1
  16. package/dist/components/renderers/stair/stair-renderer.js +172 -39
  17. package/dist/components/renderers/stair-segment/stair-segment-renderer.d.ts.map +1 -1
  18. package/dist/components/renderers/stair-segment/stair-segment-renderer.js +37 -8
  19. package/dist/components/renderers/wall/wall-renderer.d.ts.map +1 -1
  20. package/dist/components/renderers/wall/wall-renderer.js +4 -9
  21. package/dist/components/renderers/window/window-renderer.d.ts.map +1 -1
  22. package/dist/components/renderers/window/window-renderer.js +5 -2
  23. package/dist/components/viewer/frame-limiter.d.ts +6 -0
  24. package/dist/components/viewer/frame-limiter.d.ts.map +1 -0
  25. package/dist/components/viewer/frame-limiter.js +31 -0
  26. package/dist/components/viewer/ground-occluder.d.ts.map +1 -1
  27. package/dist/components/viewer/ground-occluder.js +5 -1
  28. package/dist/components/viewer/index.d.ts.map +1 -1
  29. package/dist/components/viewer/index.js +11 -11
  30. package/dist/components/viewer/post-processing.d.ts.map +1 -1
  31. package/dist/components/viewer/post-processing.js +33 -36
  32. package/dist/components/viewer/selection-manager.d.ts.map +1 -1
  33. package/dist/components/viewer/selection-manager.js +12 -1
  34. package/dist/hooks/use-node-events.d.ts.map +1 -1
  35. package/dist/hooks/use-node-events.js +2 -0
  36. package/dist/lib/materials.d.ts +4 -1
  37. package/dist/lib/materials.d.ts.map +1 -1
  38. package/dist/lib/materials.js +178 -2
  39. package/dist/lib/merged-outline-node.d.ts.map +1 -1
  40. package/dist/lib/merged-outline-node.js +11 -4
  41. package/dist/store/use-viewer.d.ts +2 -2
  42. package/dist/systems/roof/roof-materials.d.ts +5 -0
  43. package/dist/systems/roof/roof-materials.d.ts.map +1 -0
  44. package/dist/systems/roof/roof-materials.js +29 -0
  45. package/dist/systems/stair/stair-materials.d.ts +7 -0
  46. package/dist/systems/stair/stair-materials.d.ts.map +1 -0
  47. package/dist/systems/stair/stair-materials.js +33 -0
  48. package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
  49. package/dist/systems/wall/wall-cutout.js +4 -123
  50. package/dist/systems/wall/wall-materials.d.ts +16 -0
  51. package/dist/systems/wall/wall-materials.d.ts.map +1 -0
  52. package/dist/systems/wall/wall-materials.js +148 -0
  53. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"ceiling-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/ceiling/ceiling-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAgC,MAAM,kBAAkB,CAAA;AAkCjF,eAAO,MAAM,eAAe,GAAI,UAAU;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,4CA6B9D,CAAA"}
1
+ {"version":3,"file":"ceiling-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/ceiling/ceiling-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAwD,MAAM,kBAAkB,CAAA;AAkCzG,eAAO,MAAM,eAAe,GAAI,UAAU;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,4CA8B9D,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { resolveMaterial, useRegistry } from '@pascal-app/core';
2
+ import { getMaterialPresetByRef, resolveMaterial, useRegistry } from '@pascal-app/core';
3
3
  import { useMemo, useRef } from 'react';
4
4
  import { float, mix, positionWorld, smoothstep } from 'three/tsl';
5
5
  import { BackSide, FrontSide, MeshBasicNodeMaterial } from 'three/webgpu';
@@ -33,9 +33,10 @@ export const CeilingRenderer = ({ node }) => {
33
33
  useRegistry(node.id, 'ceiling', ref);
34
34
  const handlers = useNodeEvents(node, 'ceiling');
35
35
  const materials = useMemo(() => {
36
- const props = resolveMaterial(node.material);
36
+ const preset = getMaterialPresetByRef(node.materialPreset);
37
+ const props = preset?.mapProperties ?? resolveMaterial(node.material);
37
38
  const color = props.color || '#999999';
38
39
  return createCeilingMaterials(color);
39
- }, [node.material, node.material?.preset, node.material?.properties, node.material?.texture]);
40
+ }, [node.materialPreset, node.material, node.material?.preset, node.material?.properties, node.material?.texture]);
40
41
  return (_jsxs("mesh", { material: materials.bottomMaterial, ref: ref, children: [_jsx("boxGeometry", { args: [0, 0, 0] }), _jsx("mesh", { material: materials.topMaterial, name: "ceiling-grid", ...handlers, scale: 0, visible: false, children: _jsx("boxGeometry", { args: [0, 0, 0] }) }), node.children.map((childId) => (_jsx(NodeRenderer, { nodeId: childId }, childId)))] }));
41
42
  };
@@ -1 +1 @@
1
- {"version":3,"file":"door-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/door/door-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,kBAAkB,CAAA;AAM7D,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,4CA2BxD,CAAA"}
1
+ {"version":3,"file":"door-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/door/door-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAyB,MAAM,kBAAkB,CAAA;AAMvE,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,4CA8BxD,CAAA"}
@@ -1,11 +1,14 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useRegistry } from '@pascal-app/core';
3
- import { useMemo, useRef } from 'react';
2
+ import { useRegistry, useScene } from '@pascal-app/core';
3
+ import { useLayoutEffect, useMemo, useRef } from 'react';
4
4
  import { useNodeEvents } from '../../../hooks/use-node-events';
5
5
  import { createMaterial, DEFAULT_DOOR_MATERIAL } from '../../../lib/materials';
6
6
  export const DoorRenderer = ({ node }) => {
7
7
  const ref = useRef(null);
8
8
  useRegistry(node.id, 'door', ref);
9
+ useLayoutEffect(() => {
10
+ useScene.getState().markDirty(node.id);
11
+ }, [node.id]);
9
12
  const handlers = useNodeEvents(node, 'door');
10
13
  const isTransient = !!node.metadata?.isTransient;
11
14
  const material = useMemo(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"fence-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/fence/fence-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAyB,MAAM,kBAAkB,CAAA;AAMxE,eAAO,MAAM,aAAa,GAAI,UAAU;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,4CAe1D,CAAA"}
1
+ {"version":3,"file":"fence-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/fence/fence-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAyB,MAAM,kBAAkB,CAAA;AAUxE,eAAO,MAAM,aAAa,GAAI,UAAU;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,4CA2B1D,CAAA"}
@@ -2,11 +2,25 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useRegistry, useScene } from '@pascal-app/core';
3
3
  import { useLayoutEffect, useMemo, useRef } from 'react';
4
4
  import { useNodeEvents } from '../../../hooks/use-node-events';
5
- import { DEFAULT_STAIR_MATERIAL } from '../../../lib/materials';
5
+ import { createMaterial, createMaterialFromPresetRef, DEFAULT_STAIR_MATERIAL, } from '../../../lib/materials';
6
6
  export const FenceRenderer = ({ node }) => {
7
7
  const ref = useRef(null);
8
8
  const handlers = useNodeEvents(node, 'fence');
9
- const material = useMemo(() => DEFAULT_STAIR_MATERIAL, []);
9
+ const material = useMemo(() => {
10
+ const presetMaterial = createMaterialFromPresetRef(node.materialPreset);
11
+ if (presetMaterial)
12
+ return presetMaterial;
13
+ const mat = node.material;
14
+ if (!mat)
15
+ return DEFAULT_STAIR_MATERIAL;
16
+ return createMaterial(mat);
17
+ }, [
18
+ node.materialPreset,
19
+ node.material,
20
+ node.material?.preset,
21
+ node.material?.properties,
22
+ node.material?.texture,
23
+ ]);
10
24
  useRegistry(node.id, 'fence', ref);
11
25
  useLayoutEffect(() => {
12
26
  useScene.getState().markDirty(node.id);
@@ -1 +1 @@
1
- {"version":3,"file":"roof-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/roof/roof-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,kBAAkB,CAAA;AAS7D,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,4CAkCxD,CAAA"}
1
+ {"version":3,"file":"roof-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/roof/roof-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,kBAAkB,CAAA;AAS7D,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,4CAgExD,CAAA"}
@@ -1,9 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useRegistry } from '@pascal-app/core';
3
- import { useMemo, useRef } from 'react';
3
+ import { useEffect, useMemo, useRef } from 'react';
4
+ import * as THREE from 'three';
4
5
  import { useNodeEvents } from '../../../hooks/use-node-events';
5
- import { createMaterial } from '../../../lib/materials';
6
6
  import useViewer from '../../../store/use-viewer';
7
+ import { getRoofMaterialArray } from '../../../systems/roof/roof-materials';
7
8
  import { NodeRenderer } from '../node-renderer';
8
9
  import { roofDebugMaterials, roofMaterials } from './roof-materials';
9
10
  export const RoofRenderer = ({ node }) => {
@@ -11,12 +12,33 @@ export const RoofRenderer = ({ node }) => {
11
12
  useRegistry(node.id, 'roof', ref);
12
13
  const handlers = useNodeEvents(node, 'roof');
13
14
  const debugColors = useViewer((s) => s.debugColors);
14
- const customMaterial = useMemo(() => {
15
- const mat = node.material;
16
- if (!mat)
17
- return null;
18
- return createMaterial(mat);
19
- }, [node.material, node.material?.preset, node.material?.properties, node.material?.texture]);
15
+ const placeholderGeometry = useMemo(() => {
16
+ const geometry = new THREE.BufferGeometry();
17
+ geometry.setAttribute('position', new THREE.Float32BufferAttribute([], 3));
18
+ geometry.addGroup(0, 0, 0);
19
+ geometry.addGroup(0, 0, 1);
20
+ geometry.addGroup(0, 0, 2);
21
+ geometry.addGroup(0, 0, 3);
22
+ return geometry;
23
+ }, []);
24
+ const customMaterial = useMemo(() => getRoofMaterialArray(node), [
25
+ node.materialPreset,
26
+ node.material,
27
+ node.material?.preset,
28
+ node.material?.properties,
29
+ node.material?.texture,
30
+ node.topMaterial,
31
+ node.topMaterialPreset,
32
+ node.edgeMaterial,
33
+ node.edgeMaterialPreset,
34
+ node.wallMaterial,
35
+ node.wallMaterialPreset,
36
+ ]);
20
37
  const material = debugColors ? roofDebugMaterials : customMaterial || roofMaterials;
21
- return (_jsxs("group", { position: node.position, ref: ref, "rotation-y": node.rotation, visible: node.visible, ...handlers, children: [_jsx("mesh", { castShadow: true, material: material, name: "merged-roof", receiveShadow: true, children: _jsx("boxGeometry", { args: [0, 0, 0] }) }), _jsx("group", { name: "segments-wrapper", visible: false, children: (node.children ?? []).map((childId) => (_jsx(NodeRenderer, { nodeId: childId }, childId))) })] }));
38
+ useEffect(() => {
39
+ return () => {
40
+ placeholderGeometry.dispose();
41
+ };
42
+ }, [placeholderGeometry]);
43
+ return (_jsxs("group", { position: node.position, ref: ref, "rotation-y": node.rotation, visible: node.visible, ...handlers, children: [_jsx("mesh", { castShadow: true, geometry: placeholderGeometry, material: material, name: "merged-roof", receiveShadow: true }), _jsx("group", { name: "segments-wrapper", visible: false, children: (node.children ?? []).map((childId) => (_jsx(NodeRenderer, { nodeId: childId }, childId))) })] }));
22
44
  };
@@ -1 +1 @@
1
- {"version":3,"file":"roof-segment-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/roof-segment/roof-segment-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAe,MAAM,kBAAkB,CAAA;AAQpE,eAAO,MAAM,mBAAmB,GAAI,UAAU;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,4CA6BtE,CAAA"}
1
+ {"version":3,"file":"roof-segment-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/roof-segment/roof-segment-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,eAAe,EAAyB,MAAM,kBAAkB,CAAA;AAQ7G,eAAO,MAAM,mBAAmB,GAAI,UAAU;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,4CAgEtE,CAAA"}
@@ -1,21 +1,55 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useRegistry } from '@pascal-app/core';
3
- import { useMemo, useRef } from 'react';
2
+ import { useRegistry, useScene } from '@pascal-app/core';
3
+ import { useEffect, useMemo, useRef } from 'react';
4
+ import * as THREE from 'three';
4
5
  import { useNodeEvents } from '../../../hooks/use-node-events';
5
- import { createMaterial } from '../../../lib/materials';
6
6
  import useViewer from '../../../store/use-viewer';
7
+ import { getRoofMaterialArray } from '../../../systems/roof/roof-materials';
7
8
  import { roofDebugMaterials, roofMaterials } from '../roof/roof-materials';
8
9
  export const RoofSegmentRenderer = ({ node }) => {
9
10
  const ref = useRef(null);
11
+ const nodes = useScene((state) => state.nodes);
10
12
  useRegistry(node.id, 'roof-segment', ref);
11
13
  const handlers = useNodeEvents(node, 'roof-segment');
12
14
  const debugColors = useViewer((s) => s.debugColors);
15
+ const parentNode = node.parentId ? nodes[node.parentId] : undefined;
16
+ const placeholderGeometry = useMemo(() => {
17
+ const geometry = new THREE.BufferGeometry();
18
+ geometry.setAttribute('position', new THREE.Float32BufferAttribute([], 3));
19
+ geometry.addGroup(0, 0, 0);
20
+ geometry.addGroup(0, 0, 1);
21
+ geometry.addGroup(0, 0, 2);
22
+ geometry.addGroup(0, 0, 3);
23
+ return geometry;
24
+ }, []);
13
25
  const customMaterial = useMemo(() => {
14
- const mat = node.material;
15
- if (!mat)
26
+ if (node.material !== undefined || typeof node.materialPreset === 'string') {
16
27
  return null;
17
- return createMaterial(mat);
18
- }, [node.material, node.material?.preset, node.material?.properties, node.material?.texture]);
28
+ }
29
+ return parentNode ? getRoofMaterialArray(parentNode) : null;
30
+ }, [
31
+ node.materialPreset,
32
+ node.material,
33
+ node.material?.preset,
34
+ node.material?.properties,
35
+ node.material?.texture,
36
+ parentNode?.materialPreset,
37
+ parentNode?.material,
38
+ parentNode?.material?.preset,
39
+ parentNode?.material?.properties,
40
+ parentNode?.material?.texture,
41
+ parentNode?.topMaterial,
42
+ parentNode?.topMaterialPreset,
43
+ parentNode?.edgeMaterial,
44
+ parentNode?.edgeMaterialPreset,
45
+ parentNode?.wallMaterial,
46
+ parentNode?.wallMaterialPreset,
47
+ ]);
19
48
  const material = debugColors ? roofDebugMaterials : customMaterial || roofMaterials;
20
- return (_jsx("mesh", { material: material, position: node.position, ref: ref, "rotation-y": node.rotation, visible: node.visible, ...handlers, children: _jsx("boxGeometry", { args: [0, 0, 0] }) }));
49
+ useEffect(() => {
50
+ return () => {
51
+ placeholderGeometry.dispose();
52
+ };
53
+ }, [placeholderGeometry]);
54
+ return (_jsx("mesh", { geometry: placeholderGeometry, material: material, position: node.position, ref: ref, "rotation-y": node.rotation, visible: node.visible, ...handlers }));
21
55
  };
@@ -1 +1 @@
1
- {"version":3,"file":"site-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/site/site-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAwC,MAAM,kBAAkB,CAAA;AAmCtF,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,mDAgHxD,CAAA"}
1
+ {"version":3,"file":"site-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/site/site-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAwC,MAAM,kBAAkB,CAAA;AAmCtF,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,mDAyHxD,CAAA"}
@@ -43,7 +43,13 @@ export const SiteRenderer = ({ node }) => {
43
43
  lowestLevelIndex = Math.min(lowestLevelIndex, n.level);
44
44
  });
45
45
  const next = nodeList
46
- .filter((n) => n.type === 'slab' && n.visible && n.polygon.length >= 3)
46
+ .filter((n) => n.type === 'slab' &&
47
+ n.visible &&
48
+ n.polygon.length >= 3 &&
49
+ // Only recessed slabs should punch through the site ground.
50
+ // Positive slabs are real floor geometry and should not create a
51
+ // ghost footprint in the background ground fill.
52
+ (n.elevation ?? 0.05) < 0)
47
53
  .filter((n) => {
48
54
  if (!Number.isFinite(lowestLevelIndex))
49
55
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"slab-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/slab/slab-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,kBAAkB,CAAA;AAM7D,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,4CAyBxD,CAAA"}
1
+ {"version":3,"file":"slab-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/slab/slab-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,QAAQ,EAAe,MAAM,kBAAkB,CAAA;AAWrF,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,4CA0DxD,CAAA"}
@@ -1,17 +1,46 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useRegistry } from '@pascal-app/core';
3
- import { useMemo, useRef } from 'react';
2
+ import { getMaterialPresetByRef, useRegistry } from '@pascal-app/core';
3
+ import { useEffect, useMemo, useRef } from 'react';
4
+ import * as THREE from 'three';
4
5
  import { useNodeEvents } from '../../../hooks/use-node-events';
5
- import { createMaterial, DEFAULT_SLAB_MATERIAL } from '../../../lib/materials';
6
+ import { applyMaterialPresetToMaterials, createMaterial, DEFAULT_SLAB_MATERIAL, } from '../../../lib/materials';
6
7
  export const SlabRenderer = ({ node }) => {
7
8
  const ref = useRef(null);
8
9
  useRegistry(node.id, 'slab', ref);
9
10
  const handlers = useNodeEvents(node, 'slab');
10
11
  const material = useMemo(() => {
11
- const mat = node.material;
12
- if (!mat)
13
- return DEFAULT_SLAB_MATERIAL;
14
- return createMaterial(mat);
15
- }, [node.material, node.material?.preset, node.material?.properties, node.material?.texture]);
12
+ const preset = getMaterialPresetByRef(node.materialPreset);
13
+ const slabMaterial = preset
14
+ ? new THREE.MeshStandardMaterial()
15
+ : node.material
16
+ ? createMaterial(node.material).clone()
17
+ : DEFAULT_SLAB_MATERIAL.clone();
18
+ if (preset) {
19
+ // Apply the preset to the slab-owned material so async texture loads update
20
+ // the instance we actually render after refresh as well.
21
+ applyMaterialPresetToMaterials(slabMaterial, preset);
22
+ }
23
+ // Slabs participate in the WebGPU MRT scene pass. Keeping them opaque avoids
24
+ // pipeline variants that can fail when geometry is regenerated while a
25
+ // transparent/custom material is attached.
26
+ slabMaterial.transparent = false;
27
+ slabMaterial.opacity = 1;
28
+ slabMaterial.alphaMap = null;
29
+ slabMaterial.side = THREE.DoubleSide;
30
+ slabMaterial.depthWrite = true;
31
+ slabMaterial.needsUpdate = true;
32
+ return slabMaterial;
33
+ }, [
34
+ node.material,
35
+ node.material?.preset,
36
+ node.material?.properties,
37
+ node.material?.texture,
38
+ node.materialPreset,
39
+ ]);
40
+ useEffect(() => {
41
+ return () => {
42
+ material.dispose();
43
+ };
44
+ }, [material]);
16
45
  return (_jsx("mesh", { castShadow: true, receiveShadow: true, ref: ref, ...handlers, material: material, visible: node.visible, children: _jsx("boxGeometry", { args: [0, 0, 0] }) }));
17
46
  };
@@ -1 +1 @@
1
- {"version":3,"file":"stair-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/stair/stair-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,SAAS,EAAgD,MAAM,kBAAkB,CAAA;AAqC/G,eAAO,MAAM,aAAa,GAAI,UAAU;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,4CAwC1D,CAAA"}
1
+ {"version":3,"file":"stair-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/stair/stair-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EAIf,MAAM,kBAAkB,CAAA;AA0CzB,eAAO,MAAM,aAAa,GAAI,UAAU;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,4CAiG1D,CAAA"}