@pascal-app/viewer 0.5.1 → 0.7.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.
- package/dist/components/error-boundary.d.ts +7 -3
- package/dist/components/error-boundary.d.ts.map +1 -1
- package/dist/components/error-boundary.js +3 -1
- package/dist/components/renderers/ceiling/ceiling-renderer.d.ts.map +1 -1
- package/dist/components/renderers/ceiling/ceiling-renderer.js +21 -4
- package/dist/components/renderers/column/column-renderer.d.ts +5 -0
- package/dist/components/renderers/column/column-renderer.d.ts.map +1 -0
- package/dist/components/renderers/column/column-renderer.js +594 -0
- package/dist/components/renderers/door/door-renderer.d.ts.map +1 -1
- package/dist/components/renderers/door/door-renderer.js +8 -10
- package/dist/components/renderers/fence/fence-renderer.d.ts.map +1 -1
- package/dist/components/renderers/fence/fence-renderer.js +16 -2
- package/dist/components/renderers/guide/guide-renderer.js +1 -1
- package/dist/components/renderers/item/item-renderer.d.ts.map +1 -1
- package/dist/components/renderers/item/item-renderer.js +2 -1
- package/dist/components/renderers/node-renderer.d.ts.map +1 -1
- package/dist/components/renderers/node-renderer.js +3 -1
- package/dist/components/renderers/roof/roof-renderer.d.ts.map +1 -1
- package/dist/components/renderers/roof/roof-renderer.js +19 -9
- package/dist/components/renderers/roof-segment/roof-segment-renderer.d.ts.map +1 -1
- package/dist/components/renderers/roof-segment/roof-segment-renderer.js +27 -8
- package/dist/components/renderers/site/site-renderer.d.ts.map +1 -1
- package/dist/components/renderers/site/site-renderer.js +7 -1
- package/dist/components/renderers/slab/slab-renderer.d.ts.map +1 -1
- package/dist/components/renderers/slab/slab-renderer.js +48 -7
- package/dist/components/renderers/spawn/spawn-renderer.d.ts +5 -0
- package/dist/components/renderers/spawn/spawn-renderer.d.ts.map +1 -0
- package/dist/components/renderers/spawn/spawn-renderer.js +32 -0
- package/dist/components/renderers/stair/stair-renderer.d.ts.map +1 -1
- package/dist/components/renderers/stair/stair-renderer.js +154 -39
- package/dist/components/renderers/stair-segment/stair-segment-renderer.d.ts.map +1 -1
- package/dist/components/renderers/stair-segment/stair-segment-renderer.js +22 -10
- package/dist/components/renderers/wall/wall-renderer.d.ts.map +1 -1
- package/dist/components/renderers/wall/wall-renderer.js +4 -9
- package/dist/components/renderers/window/window-renderer.d.ts.map +1 -1
- package/dist/components/renderers/window/window-renderer.js +5 -2
- package/dist/components/viewer/frame-limiter.d.ts +6 -0
- package/dist/components/viewer/frame-limiter.d.ts.map +1 -0
- package/dist/components/viewer/frame-limiter.js +31 -0
- package/dist/components/viewer/ground-occluder.d.ts.map +1 -1
- package/dist/components/viewer/ground-occluder.js +5 -1
- package/dist/components/viewer/index.d.ts +2 -0
- package/dist/components/viewer/index.d.ts.map +1 -1
- package/dist/components/viewer/index.js +90 -20
- package/dist/components/viewer/post-processing.d.ts +13 -1
- package/dist/components/viewer/post-processing.d.ts.map +1 -1
- package/dist/components/viewer/post-processing.js +98 -44
- package/dist/components/viewer/selection-manager.d.ts.map +1 -1
- package/dist/components/viewer/selection-manager.js +31 -3
- package/dist/hooks/use-node-events.d.ts +9 -1
- package/dist/hooks/use-node-events.d.ts.map +1 -1
- package/dist/hooks/use-node-events.js +2 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/lib/materials.d.ts +7 -1
- package/dist/lib/materials.d.ts.map +1 -1
- package/dist/lib/materials.js +192 -2
- package/dist/lib/merged-outline-node.d.ts +2 -0
- package/dist/lib/merged-outline-node.d.ts.map +1 -1
- package/dist/lib/merged-outline-node.js +36 -9
- package/dist/store/use-viewer.d.ts +6 -6
- package/dist/store/use-viewer.d.ts.map +1 -1
- package/dist/store/use-viewer.js +2 -2
- package/dist/systems/ceiling/ceiling-system.d.ts +8 -0
- package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -0
- package/dist/systems/ceiling/ceiling-system.js +91 -0
- package/dist/systems/column/column-geometry.d.ts +22 -0
- package/dist/systems/column/column-geometry.d.ts.map +1 -0
- package/dist/systems/column/column-geometry.js +108 -0
- package/dist/systems/door/door-animation-system.d.ts +2 -0
- package/dist/systems/door/door-animation-system.d.ts.map +1 -0
- package/dist/systems/door/door-animation-system.js +53 -0
- package/dist/systems/door/door-system.d.ts +2 -0
- package/dist/systems/door/door-system.d.ts.map +1 -0
- package/dist/systems/door/door-system.js +867 -0
- package/dist/systems/fence/fence-system.d.ts +2 -0
- package/dist/systems/fence/fence-system.d.ts.map +1 -0
- package/dist/systems/fence/fence-system.js +185 -0
- package/dist/systems/item/item-system.d.ts +2 -0
- package/dist/systems/item/item-system.d.ts.map +1 -0
- package/dist/systems/item/item-system.js +44 -0
- package/dist/systems/item-mesh-metadata/compute-item-mesh-metadata.d.ts +14 -0
- package/dist/systems/item-mesh-metadata/compute-item-mesh-metadata.d.ts.map +1 -0
- package/dist/systems/item-mesh-metadata/compute-item-mesh-metadata.js +155 -0
- package/dist/systems/item-mesh-metadata/item-mesh-metadata-system.d.ts +6 -0
- package/dist/systems/item-mesh-metadata/item-mesh-metadata-system.d.ts.map +1 -0
- package/dist/systems/item-mesh-metadata/item-mesh-metadata-system.js +75 -0
- package/dist/systems/item-mesh-metadata/sync-request.d.ts +7 -0
- package/dist/systems/item-mesh-metadata/sync-request.d.ts.map +1 -0
- package/dist/systems/item-mesh-metadata/sync-request.js +25 -0
- package/dist/systems/roof/roof-materials.d.ts +5 -0
- package/dist/systems/roof/roof-materials.d.ts.map +1 -0
- package/dist/systems/roof/roof-materials.js +46 -0
- package/dist/systems/roof/roof-system.d.ts +16 -0
- package/dist/systems/roof/roof-system.d.ts.map +1 -0
- package/dist/systems/roof/roof-system.js +797 -0
- package/dist/systems/slab/slab-system.d.ts +8 -0
- package/dist/systems/slab/slab-system.d.ts.map +1 -0
- package/dist/systems/slab/slab-system.js +155 -0
- package/dist/systems/stair/stair-materials.d.ts +7 -0
- package/dist/systems/stair/stair-materials.d.ts.map +1 -0
- package/dist/systems/stair/stair-materials.js +56 -0
- package/dist/systems/stair/stair-system.d.ts +2 -0
- package/dist/systems/stair/stair-system.d.ts.map +1 -0
- package/dist/systems/stair/stair-system.js +772 -0
- package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
- package/dist/systems/wall/wall-cutout.js +4 -123
- package/dist/systems/wall/wall-materials.d.ts +16 -0
- package/dist/systems/wall/wall-materials.d.ts.map +1 -0
- package/dist/systems/wall/wall-materials.js +148 -0
- package/dist/systems/wall/wall-system.d.ts +11 -0
- package/dist/systems/wall/wall-system.d.ts.map +1 -0
- package/dist/systems/wall/wall-system.js +592 -0
- package/dist/systems/window/window-animation-system.d.ts +2 -0
- package/dist/systems/window/window-animation-system.d.ts.map +1 -0
- package/dist/systems/window/window-animation-system.js +135 -0
- package/dist/systems/window/window-system.d.ts +12 -0
- package/dist/systems/window/window-system.d.ts.map +1 -0
- package/dist/systems/window/window-system.js +1430 -0
- package/package.json +6 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wall-cutout.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-cutout.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wall-cutout.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-cutout.tsx"],"names":[],"mappings":"AAsCA,eAAO,MAAM,UAAU,YAkHtB,CAAA"}
|
|
@@ -1,129 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { emitter, sceneRegistry, useScene } from '@pascal-app/core';
|
|
2
2
|
import { useFrame } from '@react-three/fiber';
|
|
3
3
|
import { useEffect, useRef } from 'react';
|
|
4
|
-
import {
|
|
5
|
-
import { Fn, float, fract, length, mix, positionLocal, smoothstep, step, vec2 } from 'three/tsl';
|
|
6
|
-
import { MeshStandardNodeMaterial, Vector3 } from 'three/webgpu';
|
|
4
|
+
import { Vector3 } from 'three/webgpu';
|
|
7
5
|
import useViewer from '../../store/use-viewer';
|
|
6
|
+
import { getMaterialsForWall } from './wall-materials';
|
|
8
7
|
const tmpVec = new Vector3();
|
|
9
8
|
const u = new Vector3();
|
|
10
9
|
const v = new Vector3();
|
|
11
|
-
const DEFAULT_WALL_COLOR = '#f2f0ed';
|
|
12
|
-
const WALL_HIGHLIGHT_PROFILES = {
|
|
13
|
-
delete: {
|
|
14
|
-
color: new Color('#dc2626'),
|
|
15
|
-
blend: 0.78,
|
|
16
|
-
emissiveIntensity: 0.46,
|
|
17
|
-
},
|
|
18
|
-
selection: {
|
|
19
|
-
color: new Color('#818cf8'),
|
|
20
|
-
blend: 0.32,
|
|
21
|
-
emissiveIntensity: 0.42,
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
const dotPattern = Fn(() => {
|
|
25
|
-
const scale = float(0.1);
|
|
26
|
-
const dotSize = float(0.3);
|
|
27
|
-
const uv = vec2(positionLocal.x, positionLocal.y).div(scale);
|
|
28
|
-
const gridUV = fract(uv);
|
|
29
|
-
const dist = length(gridUV.sub(0.5));
|
|
30
|
-
const dots = step(dist, dotSize.mul(0.5));
|
|
31
|
-
const fadeHeight = float(2.5);
|
|
32
|
-
const yFade = float(1).sub(smoothstep(float(0), fadeHeight, positionLocal.y));
|
|
33
|
-
return dots.mul(yFade);
|
|
34
|
-
});
|
|
35
|
-
const wallMaterialCache = new Map();
|
|
36
|
-
const presetColors = {
|
|
37
|
-
white: '#ffffff',
|
|
38
|
-
brick: '#8b4513',
|
|
39
|
-
concrete: '#808080',
|
|
40
|
-
wood: '#deb887',
|
|
41
|
-
glass: '#87ceeb',
|
|
42
|
-
metal: '#c0c0c0',
|
|
43
|
-
plaster: '#f5f5dc',
|
|
44
|
-
tile: '#dcdcdc',
|
|
45
|
-
marble: '#f5f5f5',
|
|
46
|
-
};
|
|
47
|
-
function getMaterialHash(wallNode) {
|
|
48
|
-
if (!wallNode.material)
|
|
49
|
-
return 'none';
|
|
50
|
-
const mat = wallNode.material;
|
|
51
|
-
if (mat.preset && mat.preset !== 'custom') {
|
|
52
|
-
return `preset-${mat.preset}`;
|
|
53
|
-
}
|
|
54
|
-
if (mat.properties) {
|
|
55
|
-
return `props-${mat.properties.color}-${mat.properties.roughness}-${mat.properties.metalness}`;
|
|
56
|
-
}
|
|
57
|
-
return 'default';
|
|
58
|
-
}
|
|
59
|
-
function getPresetColor(preset) {
|
|
60
|
-
return presetColors[preset] ?? '#ffffff';
|
|
61
|
-
}
|
|
62
|
-
function getHighlightedColor(color, kind) {
|
|
63
|
-
const profile = WALL_HIGHLIGHT_PROFILES[kind];
|
|
64
|
-
return new Color(color).lerp(profile.color, profile.blend);
|
|
65
|
-
}
|
|
66
|
-
function createHighlightedWallMaterial(material, baseColor, kind) {
|
|
67
|
-
const highlightedMaterial = material.clone();
|
|
68
|
-
const highlightedColor = getHighlightedColor(baseColor, kind);
|
|
69
|
-
const profile = WALL_HIGHLIGHT_PROFILES[kind];
|
|
70
|
-
highlightedMaterial.color = highlightedColor;
|
|
71
|
-
highlightedMaterial.emissive = highlightedColor.clone();
|
|
72
|
-
highlightedMaterial.emissiveIntensity = profile.emissiveIntensity;
|
|
73
|
-
return highlightedMaterial;
|
|
74
|
-
}
|
|
75
|
-
function getMaterialsForWall(wallNode) {
|
|
76
|
-
const cacheKey = wallNode.id;
|
|
77
|
-
const materialHash = getMaterialHash(wallNode);
|
|
78
|
-
const existing = wallMaterialCache.get(cacheKey);
|
|
79
|
-
if (existing && existing.materialHash === materialHash) {
|
|
80
|
-
return existing;
|
|
81
|
-
}
|
|
82
|
-
if (existing) {
|
|
83
|
-
existing.visible.dispose();
|
|
84
|
-
existing.invisible.dispose();
|
|
85
|
-
existing.deleteVisible.dispose();
|
|
86
|
-
existing.deleteInvisible.dispose();
|
|
87
|
-
existing.highlightedVisible.dispose();
|
|
88
|
-
existing.highlightedInvisible.dispose();
|
|
89
|
-
}
|
|
90
|
-
let userColor = DEFAULT_WALL_COLOR;
|
|
91
|
-
if (wallNode.material?.properties?.color) {
|
|
92
|
-
userColor = wallNode.material.properties.color;
|
|
93
|
-
}
|
|
94
|
-
else if (wallNode.material?.preset && wallNode.material.preset !== 'custom') {
|
|
95
|
-
userColor = getPresetColor(wallNode.material.preset);
|
|
96
|
-
}
|
|
97
|
-
const visibleMat = wallNode.material
|
|
98
|
-
? new MeshStandardNodeMaterial({
|
|
99
|
-
color: userColor,
|
|
100
|
-
roughness: 1,
|
|
101
|
-
metalness: 0,
|
|
102
|
-
})
|
|
103
|
-
: baseMaterial.clone();
|
|
104
|
-
const invisibleMat = new MeshStandardNodeMaterial({
|
|
105
|
-
transparent: true,
|
|
106
|
-
opacityNode: mix(float(0.0), float(0.24), dotPattern()),
|
|
107
|
-
color: userColor,
|
|
108
|
-
depthWrite: false,
|
|
109
|
-
emissive: userColor,
|
|
110
|
-
});
|
|
111
|
-
const highlightedVisible = createHighlightedWallMaterial(visibleMat, userColor, 'selection');
|
|
112
|
-
const highlightedInvisible = createHighlightedWallMaterial(invisibleMat, userColor, 'selection');
|
|
113
|
-
const deleteVisible = createHighlightedWallMaterial(visibleMat, userColor, 'delete');
|
|
114
|
-
const deleteInvisible = createHighlightedWallMaterial(invisibleMat, userColor, 'delete');
|
|
115
|
-
const result = {
|
|
116
|
-
visible: visibleMat,
|
|
117
|
-
invisible: invisibleMat,
|
|
118
|
-
deleteVisible,
|
|
119
|
-
deleteInvisible,
|
|
120
|
-
highlightedVisible,
|
|
121
|
-
highlightedInvisible,
|
|
122
|
-
materialHash,
|
|
123
|
-
};
|
|
124
|
-
wallMaterialCache.set(cacheKey, result);
|
|
125
|
-
return result;
|
|
126
|
-
}
|
|
127
10
|
function getWallHideState(wallNode, wallMesh, wallMode, cameraDir) {
|
|
128
11
|
let hideWall = wallNode.frontSide === 'interior' && wallNode.backSide === 'interior';
|
|
129
12
|
if (wallMode === 'up') {
|
|
@@ -206,9 +89,7 @@ export const WallCutout = () => {
|
|
|
206
89
|
? materials.deleteVisible
|
|
207
90
|
: isSelectionHighlighted
|
|
208
91
|
? materials.highlightedVisible
|
|
209
|
-
:
|
|
210
|
-
? materials.visible
|
|
211
|
-
: baseMaterial;
|
|
92
|
+
: materials.visible;
|
|
212
93
|
}
|
|
213
94
|
});
|
|
214
95
|
lastWallMode.current = wallMode;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type WallNode } from '@pascal-app/core';
|
|
2
|
+
import { type Material } from 'three';
|
|
3
|
+
export type WallMaterialArray = [Material, Material, Material];
|
|
4
|
+
export interface WallMaterials {
|
|
5
|
+
visible: WallMaterialArray;
|
|
6
|
+
invisible: WallMaterialArray;
|
|
7
|
+
deleteVisible: WallMaterialArray;
|
|
8
|
+
deleteInvisible: WallMaterialArray;
|
|
9
|
+
highlightedVisible: WallMaterialArray;
|
|
10
|
+
highlightedInvisible: WallMaterialArray;
|
|
11
|
+
materialHash: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function getWallMaterialHash(wallNode: WallNode): string;
|
|
14
|
+
export declare function getMaterialsForWall(wallNode: WallNode): WallMaterials;
|
|
15
|
+
export declare function getVisibleWallMaterials(wallNode: WallNode): WallMaterialArray;
|
|
16
|
+
//# sourceMappingURL=wall-materials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wall-materials.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-materials.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,QAAQ,EAEd,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAS,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAA;AAwB5C,MAAM,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;AAE9D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,iBAAiB,CAAA;IAC1B,SAAS,EAAE,iBAAiB,CAAA;IAC5B,aAAa,EAAE,iBAAiB,CAAA;IAChC,eAAe,EAAE,iBAAiB,CAAA;IAClC,kBAAkB,EAAE,iBAAiB,CAAA;IACrC,oBAAoB,EAAE,iBAAiB,CAAA;IACvC,YAAY,EAAE,MAAM,CAAA;CACrB;AA4GD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAS9D;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,aAAa,CA2DrE;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,GAAG,iBAAiB,CAE7E"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { getEffectiveWallSurfaceMaterial, getMaterialPresetByRef, getWallSurfaceMaterialSignature, resolveMaterial, } from '@pascal-app/core';
|
|
2
|
+
import { Color } from 'three';
|
|
3
|
+
import { Fn, float, fract, length, mix, positionLocal, smoothstep, step, vec2 } from 'three/tsl';
|
|
4
|
+
import { MeshStandardNodeMaterial } from 'three/webgpu';
|
|
5
|
+
import { baseMaterial, createMaterial, createMaterialFromPresetRef } from '../../lib/materials';
|
|
6
|
+
const DEFAULT_WALL_COLOR = '#f2f0ed';
|
|
7
|
+
const WALL_HIGHLIGHT_PROFILES = {
|
|
8
|
+
delete: {
|
|
9
|
+
color: new Color('#dc2626'),
|
|
10
|
+
blend: 0.76,
|
|
11
|
+
emissiveBlend: 0.92,
|
|
12
|
+
emissiveIntensity: 0.46,
|
|
13
|
+
},
|
|
14
|
+
selection: {
|
|
15
|
+
color: new Color('#818cf8'),
|
|
16
|
+
blend: 0.32,
|
|
17
|
+
emissiveBlend: 0.7,
|
|
18
|
+
emissiveIntensity: 0.42,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
const wallMaterialCache = new Map();
|
|
22
|
+
const dotPattern = Fn(() => {
|
|
23
|
+
const scale = float(0.1);
|
|
24
|
+
const dotSize = float(0.3);
|
|
25
|
+
const uv = vec2(positionLocal.x, positionLocal.y).div(scale);
|
|
26
|
+
const gridUV = fract(uv);
|
|
27
|
+
const dist = length(gridUV.sub(0.5));
|
|
28
|
+
const dots = step(dist, dotSize.mul(0.5));
|
|
29
|
+
const fadeHeight = float(2.5);
|
|
30
|
+
const yFade = float(1).sub(smoothstep(float(0), fadeHeight, positionLocal.y));
|
|
31
|
+
return dots.mul(yFade);
|
|
32
|
+
});
|
|
33
|
+
function getSurfaceVisibleMaterial(spec) {
|
|
34
|
+
if (spec.materialPreset) {
|
|
35
|
+
return createMaterialFromPresetRef(spec.materialPreset) ?? baseMaterial;
|
|
36
|
+
}
|
|
37
|
+
if (spec.material) {
|
|
38
|
+
return createMaterial(spec.material);
|
|
39
|
+
}
|
|
40
|
+
return baseMaterial;
|
|
41
|
+
}
|
|
42
|
+
function getSurfaceColor(spec, fallback = DEFAULT_WALL_COLOR) {
|
|
43
|
+
const preset = getMaterialPresetByRef(spec.materialPreset);
|
|
44
|
+
if (preset?.mapProperties?.color) {
|
|
45
|
+
return preset.mapProperties.color;
|
|
46
|
+
}
|
|
47
|
+
if (spec.material) {
|
|
48
|
+
return resolveMaterial(spec.material).color;
|
|
49
|
+
}
|
|
50
|
+
return fallback;
|
|
51
|
+
}
|
|
52
|
+
function getHighlightedColor(color, kind) {
|
|
53
|
+
const profile = WALL_HIGHLIGHT_PROFILES[kind];
|
|
54
|
+
return color.clone().lerp(profile.color, profile.blend);
|
|
55
|
+
}
|
|
56
|
+
function createHighlightedWallMaterial(material, kind) {
|
|
57
|
+
const highlightedMaterial = material.clone();
|
|
58
|
+
const profile = WALL_HIGHLIGHT_PROFILES[kind];
|
|
59
|
+
if ('color' in highlightedMaterial && highlightedMaterial.color) {
|
|
60
|
+
highlightedMaterial.color = getHighlightedColor(highlightedMaterial.color, kind);
|
|
61
|
+
}
|
|
62
|
+
if ('emissive' in highlightedMaterial && highlightedMaterial.emissive) {
|
|
63
|
+
highlightedMaterial.emissive = highlightedMaterial.emissive
|
|
64
|
+
.clone()
|
|
65
|
+
.lerp(profile.color, profile.emissiveBlend);
|
|
66
|
+
}
|
|
67
|
+
if ('emissiveIntensity' in highlightedMaterial) {
|
|
68
|
+
highlightedMaterial.emissiveIntensity = Math.max(highlightedMaterial.emissiveIntensity ?? 0, profile.emissiveIntensity);
|
|
69
|
+
}
|
|
70
|
+
highlightedMaterial.needsUpdate = true;
|
|
71
|
+
return highlightedMaterial;
|
|
72
|
+
}
|
|
73
|
+
function createInvisibleWallMaterial(color) {
|
|
74
|
+
return new MeshStandardNodeMaterial({
|
|
75
|
+
transparent: true,
|
|
76
|
+
opacityNode: mix(float(0.0), float(0.24), dotPattern()),
|
|
77
|
+
color,
|
|
78
|
+
depthWrite: false,
|
|
79
|
+
emissive: color,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function mapWallMaterialArray(materials, iteratee) {
|
|
83
|
+
return materials.map(iteratee);
|
|
84
|
+
}
|
|
85
|
+
function disposeOwnedMaterials(materials) {
|
|
86
|
+
const owned = new Set();
|
|
87
|
+
materials.forEach((entry) => {
|
|
88
|
+
entry.forEach((material) => {
|
|
89
|
+
owned.add(material);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
owned.forEach((material) => {
|
|
93
|
+
material.dispose();
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
export function getWallMaterialHash(wallNode) {
|
|
97
|
+
return JSON.stringify({
|
|
98
|
+
interior: getWallSurfaceMaterialSignature(getEffectiveWallSurfaceMaterial(wallNode, 'interior')),
|
|
99
|
+
exterior: getWallSurfaceMaterialSignature(getEffectiveWallSurfaceMaterial(wallNode, 'exterior')),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
export function getMaterialsForWall(wallNode) {
|
|
103
|
+
const cacheKey = wallNode.id;
|
|
104
|
+
const materialHash = getWallMaterialHash(wallNode);
|
|
105
|
+
const existing = wallMaterialCache.get(cacheKey);
|
|
106
|
+
if (existing && existing.materialHash === materialHash) {
|
|
107
|
+
return existing;
|
|
108
|
+
}
|
|
109
|
+
if (existing) {
|
|
110
|
+
disposeOwnedMaterials([
|
|
111
|
+
existing.invisible,
|
|
112
|
+
existing.deleteVisible,
|
|
113
|
+
existing.deleteInvisible,
|
|
114
|
+
existing.highlightedVisible,
|
|
115
|
+
existing.highlightedInvisible,
|
|
116
|
+
]);
|
|
117
|
+
}
|
|
118
|
+
const interiorSpec = getEffectiveWallSurfaceMaterial(wallNode, 'interior');
|
|
119
|
+
const exteriorSpec = getEffectiveWallSurfaceMaterial(wallNode, 'exterior');
|
|
120
|
+
const visible = [
|
|
121
|
+
baseMaterial,
|
|
122
|
+
getSurfaceVisibleMaterial(interiorSpec),
|
|
123
|
+
getSurfaceVisibleMaterial(exteriorSpec),
|
|
124
|
+
];
|
|
125
|
+
const invisible = [
|
|
126
|
+
createInvisibleWallMaterial(DEFAULT_WALL_COLOR),
|
|
127
|
+
createInvisibleWallMaterial(getSurfaceColor(interiorSpec, DEFAULT_WALL_COLOR)),
|
|
128
|
+
createInvisibleWallMaterial(getSurfaceColor(exteriorSpec, DEFAULT_WALL_COLOR)),
|
|
129
|
+
];
|
|
130
|
+
const highlightedVisible = mapWallMaterialArray(visible, (material) => createHighlightedWallMaterial(material, 'selection'));
|
|
131
|
+
const highlightedInvisible = mapWallMaterialArray(invisible, (material) => createHighlightedWallMaterial(material, 'selection'));
|
|
132
|
+
const deleteVisible = mapWallMaterialArray(visible, (material) => createHighlightedWallMaterial(material, 'delete'));
|
|
133
|
+
const deleteInvisible = mapWallMaterialArray(invisible, (material) => createHighlightedWallMaterial(material, 'delete'));
|
|
134
|
+
const result = {
|
|
135
|
+
visible,
|
|
136
|
+
invisible,
|
|
137
|
+
deleteVisible,
|
|
138
|
+
deleteInvisible,
|
|
139
|
+
highlightedVisible,
|
|
140
|
+
highlightedInvisible,
|
|
141
|
+
materialHash,
|
|
142
|
+
};
|
|
143
|
+
wallMaterialCache.set(cacheKey, result);
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
export function getVisibleWallMaterials(wallNode) {
|
|
147
|
+
return getMaterialsForWall(wallNode).visible;
|
|
148
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type AnyNode, type WallMiterData, type WallNode } from '@pascal-app/core';
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
export declare const WallSystem: () => null;
|
|
4
|
+
/**
|
|
5
|
+
* Generates extruded wall geometry with mitering and cutouts
|
|
6
|
+
*
|
|
7
|
+
* Key insight from demo: polygon is built in WORLD coordinates first,
|
|
8
|
+
* then we transform to wall-local for the 3D mesh.
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateExtrudedWall(wallNode: WallNode, childrenNodes: AnyNode[], miterData: WallMiterData, slabElevation?: number): THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap>;
|
|
11
|
+
//# sourceMappingURL=wall-system.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wall-system.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-system.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAkBZ,KAAK,aAAa,EAClB,KAAK,QAAQ,EAEd,MAAM,kBAAkB,CAAA;AAEzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA6R9B,eAAO,MAAM,UAAU,YAuDtB,CAAA;AA0DD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,OAAO,EAAE,EACxB,SAAS,EAAE,aAAa,EACxB,aAAa,SAAI,oFA0GlB"}
|