@pascal-app/core 0.7.0 → 0.8.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 (76) hide show
  1. package/dist/events/bus.d.ts +9 -6
  2. package/dist/events/bus.d.ts.map +1 -1
  3. package/dist/events/bus.js +1 -1
  4. package/dist/lib/polygon-geometry.d.ts.map +1 -1
  5. package/dist/lib/space-detection.d.ts.map +1 -1
  6. package/dist/lib/space-detection.js +10 -8
  7. package/dist/material-library.d.ts.map +1 -1
  8. package/dist/material-library.js +20 -1
  9. package/dist/schema/asset-url.test.js +0 -4
  10. package/dist/schema/material.d.ts +2 -2
  11. package/dist/schema/nodes/ceiling.d.ts +1 -1
  12. package/dist/schema/nodes/column.d.ts +1 -1
  13. package/dist/schema/nodes/door.d.ts +1 -1
  14. package/dist/schema/nodes/fence.d.ts +2 -2
  15. package/dist/schema/nodes/fence.js +2 -2
  16. package/dist/schema/nodes/item.d.ts +12 -0
  17. package/dist/schema/nodes/item.d.ts.map +1 -1
  18. package/dist/schema/nodes/item.js +12 -0
  19. package/dist/schema/nodes/roof-segment.d.ts +3 -3
  20. package/dist/schema/nodes/roof.d.ts +6 -6
  21. package/dist/schema/nodes/roof.d.ts.map +1 -1
  22. package/dist/schema/nodes/roof.js +5 -5
  23. package/dist/schema/nodes/site.d.ts +6 -0
  24. package/dist/schema/nodes/site.d.ts.map +1 -1
  25. package/dist/schema/nodes/slab.d.ts +1 -1
  26. package/dist/schema/nodes/stair-segment.d.ts +1 -1
  27. package/dist/schema/nodes/stair.d.ts +6 -6
  28. package/dist/schema/nodes/stair.d.ts.map +1 -1
  29. package/dist/schema/nodes/stair.js +9 -7
  30. package/dist/schema/nodes/wall.d.ts +3 -3
  31. package/dist/schema/nodes/window.d.ts +1 -1
  32. package/dist/schema/types.d.ts +33 -21
  33. package/dist/schema/types.d.ts.map +1 -1
  34. package/dist/store/actions/node-actions.d.ts.map +1 -1
  35. package/dist/store/actions/node-actions.js +7 -5
  36. package/dist/store/use-scene.d.ts.map +1 -1
  37. package/dist/store/use-scene.js +11 -5
  38. package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -1
  39. package/dist/systems/stair/stair-opening-sync.js +17 -44
  40. package/dist/systems/stair/stair-opening-sync.test.js +0 -2
  41. package/dist/systems/wall/wall-curve.d.ts +1 -1
  42. package/dist/systems/wall/wall-curve.d.ts.map +1 -1
  43. package/dist/systems/wall/wall-curve.js +1 -1
  44. package/dist/systems/wall/wall-mitering.d.ts.map +1 -1
  45. package/dist/systems/wall/wall-mitering.js +2 -6
  46. package/package.json +4 -3
  47. package/dist/materials.d.ts +0 -10
  48. package/dist/materials.d.ts.map +0 -1
  49. package/dist/materials.js +0 -22
  50. package/dist/systems/ceiling/ceiling-system.d.ts +0 -8
  51. package/dist/systems/ceiling/ceiling-system.d.ts.map +0 -1
  52. package/dist/systems/ceiling/ceiling-system.js +0 -92
  53. package/dist/systems/door/door-system.d.ts +0 -2
  54. package/dist/systems/door/door-system.d.ts.map +0 -1
  55. package/dist/systems/door/door-system.js +0 -195
  56. package/dist/systems/fence/fence-system.d.ts +0 -2
  57. package/dist/systems/fence/fence-system.d.ts.map +0 -1
  58. package/dist/systems/fence/fence-system.js +0 -187
  59. package/dist/systems/item/item-system.d.ts +0 -2
  60. package/dist/systems/item/item-system.d.ts.map +0 -1
  61. package/dist/systems/item/item-system.js +0 -48
  62. package/dist/systems/roof/roof-system.d.ts +0 -16
  63. package/dist/systems/roof/roof-system.d.ts.map +0 -1
  64. package/dist/systems/roof/roof-system.js +0 -797
  65. package/dist/systems/slab/slab-system.d.ts +0 -8
  66. package/dist/systems/slab/slab-system.d.ts.map +0 -1
  67. package/dist/systems/slab/slab-system.js +0 -214
  68. package/dist/systems/stair/stair-system.d.ts +0 -2
  69. package/dist/systems/stair/stair-system.d.ts.map +0 -1
  70. package/dist/systems/stair/stair-system.js +0 -776
  71. package/dist/systems/wall/wall-system.d.ts +0 -12
  72. package/dist/systems/wall/wall-system.d.ts.map +0 -1
  73. package/dist/systems/wall/wall-system.js +0 -455
  74. package/dist/systems/window/window-system.d.ts +0 -2
  75. package/dist/systems/window/window-system.d.ts.map +0 -1
  76. package/dist/systems/window/window-system.js +0 -131
@@ -1,8 +0,0 @@
1
- import * as THREE from 'three';
2
- import type { SlabNode } from '../../schema';
3
- export declare const SlabSystem: () => null;
4
- /**
5
- * Generates extruded slab geometry from polygon
6
- */
7
- export declare function generateSlabGeometry(slabNode: SlabNode): THREE.BufferGeometry;
8
- //# sourceMappingURL=slab-system.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slab-system.d.ts","sourceRoot":"","sources":["../../../src/systems/slab/slab-system.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,KAAK,EAAa,QAAQ,EAAE,MAAM,cAAc,CAAA;AAcvD,eAAO,MAAM,UAAU,YAwBtB,CAAA;AAmFD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,KAAK,CAAC,cAAc,CAG7E"}
@@ -1,214 +0,0 @@
1
- import { useFrame } from '@react-three/fiber';
2
- import * as THREE from 'three';
3
- import { sceneRegistry } from '../../hooks/scene-registry/scene-registry';
4
- import { insetPolygonFromCentroid, simplifyClosedPolygon } from '../../lib/polygon-geometry';
5
- import useScene from '../../store/use-scene';
6
- function ensureUv2Attribute(geometry) {
7
- const uv = geometry.getAttribute('uv');
8
- if (!uv)
9
- return;
10
- geometry.setAttribute('uv2', new THREE.Float32BufferAttribute(Array.from(uv.array), 2));
11
- }
12
- // ============================================================================
13
- // SLAB SYSTEM
14
- // ============================================================================
15
- export const SlabSystem = () => {
16
- const dirtyNodes = useScene((state) => state.dirtyNodes);
17
- const clearDirty = useScene((state) => state.clearDirty);
18
- useFrame(() => {
19
- if (dirtyNodes.size === 0)
20
- return;
21
- const nodes = useScene.getState().nodes;
22
- // Process dirty slabs
23
- dirtyNodes.forEach((id) => {
24
- const node = nodes[id];
25
- if (!node || node.type !== 'slab')
26
- return;
27
- const mesh = sceneRegistry.nodes.get(id);
28
- if (mesh) {
29
- updateSlabGeometry(node, mesh);
30
- clearDirty(id);
31
- }
32
- // If mesh not found, keep it dirty for next frame
33
- });
34
- }, 1);
35
- return null;
36
- };
37
- /**
38
- * Updates the geometry for a single slab
39
- */
40
- function updateSlabGeometry(node, mesh) {
41
- const newGeo = generateSlabGeometry(node);
42
- ensureUv2Attribute(newGeo);
43
- mesh.geometry.dispose();
44
- mesh.geometry = newGeo;
45
- // For negative elevation, shift the mesh down so the top face sits at Y=elevation
46
- // rather than at Y=0. Positive elevation stays at Y=0 (slab sits at floor level).
47
- const elevation = node.elevation ?? 0.05;
48
- mesh.position.y = elevation < 0 ? elevation : 0;
49
- }
50
- /** Half of default wall thickness — used to extend slab geometry under walls */
51
- const SLAB_OUTSET = 0.05;
52
- const AUTO_SLAB_INSET = 0.02;
53
- const AUTO_SLAB_SIMPLIFY_TOLERANCE = 0.08;
54
- function getRenderableSlabPolygon(slabNode) {
55
- return slabNode.autoFromWalls
56
- ? simplifyClosedPolygon(insetPolygonFromCentroid(slabNode.polygon, AUTO_SLAB_INSET), AUTO_SLAB_SIMPLIFY_TOLERANCE)
57
- : outsetPolygon(slabNode.polygon, SLAB_OUTSET);
58
- }
59
- /**
60
- * Expand a polygon outward by a uniform distance.
61
- * Offsets each edge outward then intersects consecutive offset edges.
62
- */
63
- function outsetPolygon(polygon, amount) {
64
- const n = polygon.length;
65
- if (n < 3)
66
- return polygon;
67
- // Determine winding via signed area
68
- let area2 = 0;
69
- for (let i = 0; i < n; i++) {
70
- const j = (i + 1) % n;
71
- area2 += polygon[i][0] * polygon[j][1] - polygon[j][0] * polygon[i][1];
72
- }
73
- const s = area2 >= 0 ? 1 : -1;
74
- // Offset each edge outward by amount
75
- const offEdges = [];
76
- for (let i = 0; i < n; i++) {
77
- const j = (i + 1) % n;
78
- const dx = polygon[j][0] - polygon[i][0];
79
- const dz = polygon[j][1] - polygon[i][1];
80
- const len = Math.sqrt(dx * dx + dz * dz);
81
- if (len < 1e-9) {
82
- offEdges.push([polygon[i][0], polygon[i][1], dx, dz]);
83
- continue;
84
- }
85
- const nx = ((s * dz) / len) * amount;
86
- const nz = ((s * -dx) / len) * amount;
87
- offEdges.push([polygon[i][0] + nx, polygon[i][1] + nz, dx, dz]);
88
- }
89
- // Intersect consecutive offset edges to get new vertices
90
- const result = [];
91
- for (let i = 0; i < n; i++) {
92
- const j = (i + 1) % n;
93
- const [ax, az, adx, adz] = offEdges[i];
94
- const [bx, bz, bdx, bdz] = offEdges[j];
95
- const denom = adx * bdz - adz * bdx;
96
- if (Math.abs(denom) < 1e-9) {
97
- // Parallel edges — use offset endpoint
98
- result.push([ax + adx, az + adz]);
99
- }
100
- else {
101
- const t = ((bx - ax) * bdz - (bz - az) * bdx) / denom;
102
- result.push([ax + t * adx, az + t * adz]);
103
- }
104
- }
105
- return result;
106
- }
107
- /**
108
- * Generates extruded slab geometry from polygon
109
- */
110
- export function generateSlabGeometry(slabNode) {
111
- const elevation = slabNode.elevation ?? 0.05;
112
- return elevation < 0 ? generatePoolGeometry(slabNode) : generatePositiveSlabGeometry(slabNode);
113
- }
114
- /**
115
- * Standard slab: flat extrusion upward from Y=0 by elevation thickness.
116
- */
117
- function generatePositiveSlabGeometry(slabNode) {
118
- const polygon = getRenderableSlabPolygon(slabNode);
119
- const elevation = slabNode.elevation ?? 0.05;
120
- if (polygon.length < 3)
121
- return new THREE.BufferGeometry();
122
- const shape = new THREE.Shape();
123
- shape.moveTo(polygon[0][0], -polygon[0][1]);
124
- for (let i = 1; i < polygon.length; i++)
125
- shape.lineTo(polygon[i][0], -polygon[i][1]);
126
- shape.closePath();
127
- for (const holePolygon of slabNode.holes ?? []) {
128
- if (holePolygon.length < 3)
129
- continue;
130
- const holePath = new THREE.Path();
131
- holePath.moveTo(holePolygon[0][0], -holePolygon[0][1]);
132
- for (let i = 1; i < holePolygon.length; i++)
133
- holePath.lineTo(holePolygon[i][0], -holePolygon[i][1]);
134
- holePath.closePath();
135
- shape.holes.push(holePath);
136
- }
137
- const geometry = new THREE.ExtrudeGeometry(shape, { depth: elevation, bevelEnabled: false });
138
- geometry.rotateX(-Math.PI / 2);
139
- geometry.computeVertexNormals();
140
- return geometry;
141
- }
142
- /**
143
- * Pool / recessed slab: floor cap at Y=0 (local) + inner walls up to Y=|elevation|.
144
- * No top cap — the opening at ground level is handled by the ground occluder hole.
145
- * mesh.position.y must be set to elevation so the floor sits at the correct world Y.
146
- *
147
- * Geometry is built directly in 3D (Y-up) to avoid rotation confusion:
148
- * - floor in XZ plane at Y=0, normals pointing +Y (visible when looking down into pool)
149
- * - walls from Y=0 to Y=depth, inward-facing normals (visible from inside pool)
150
- */
151
- function generatePoolGeometry(slabNode) {
152
- const polygon = getRenderableSlabPolygon(slabNode);
153
- const depth = Math.abs(slabNode.elevation ?? 0.05);
154
- if (polygon.length < 3)
155
- return new THREE.BufferGeometry();
156
- const positions = [];
157
- const uvs = [];
158
- const indices = [];
159
- const n = polygon.length;
160
- const bounds = new THREE.Box2();
161
- for (const [x, z] of polygon) {
162
- bounds.expandByPoint(new THREE.Vector2(x, z));
163
- }
164
- for (const hole of slabNode.holes ?? []) {
165
- for (const [x, z] of hole) {
166
- bounds.expandByPoint(new THREE.Vector2(x, z));
167
- }
168
- }
169
- const floorWidth = Math.max(bounds.max.x - bounds.min.x, 0.001);
170
- const floorHeight = Math.max(bounds.max.y - bounds.min.y, 0.001);
171
- const pushFloorVertex = (x, y, z) => {
172
- positions.push(x, y, z);
173
- uvs.push((x - bounds.min.x) / floorWidth, (z - bounds.min.y) / floorHeight);
174
- };
175
- const pushWallVertex = (x, y, z, u, v) => {
176
- positions.push(x, y, z);
177
- uvs.push(u, v);
178
- };
179
- // --- Floor at Y=0 ---
180
- for (const [x, z] of polygon)
181
- pushFloorVertex(x, 0, z);
182
- const pts2d = polygon.map(([x, z]) => new THREE.Vector2(x, z));
183
- const holesPts2d = (slabNode.holes ?? []).map((h) => h.map(([x, z]) => new THREE.Vector2(x, z)));
184
- for (const hole of slabNode.holes ?? []) {
185
- for (const [x, z] of hole)
186
- pushFloorVertex(x, 0, z);
187
- }
188
- const floorTris = THREE.ShapeUtils.triangulateShape(pts2d, holesPts2d);
189
- for (const tri of floorTris) {
190
- // Reversed winding → normals point +Y (upward) in XZ plane
191
- indices.push(tri[0], tri[2], tri[1]);
192
- }
193
- // --- Inner walls (no top cap at Y=depth) ---
194
- // Standard winding on a CCW polygon in XZ gives inward-facing normals.
195
- for (let i = 0; i < n; i++) {
196
- const j = (i + 1) % n;
197
- const [x0, z0] = polygon[i];
198
- const [x1, z1] = polygon[j];
199
- const vBase = positions.length / 3;
200
- const segmentLength = Math.max(Math.hypot(x1 - x0, z1 - z0), 0.001);
201
- pushWallVertex(x0, 0, z0, 0, 0); // v0 — floor level
202
- pushWallVertex(x1, 0, z1, segmentLength, 0); // v1 — floor level
203
- pushWallVertex(x1, depth, z1, segmentLength, depth); // v2 — ground level
204
- pushWallVertex(x0, depth, z0, 0, depth); // v3 — ground level
205
- indices.push(vBase, vBase + 1, vBase + 2);
206
- indices.push(vBase, vBase + 2, vBase + 3);
207
- }
208
- const geo = new THREE.BufferGeometry();
209
- geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
210
- geo.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));
211
- geo.setIndex(indices);
212
- geo.computeVertexNormals();
213
- return geo;
214
- }
@@ -1,2 +0,0 @@
1
- export declare const StairSystem: () => null;
2
- //# sourceMappingURL=stair-system.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"stair-system.d.ts","sourceRoot":"","sources":["../../../src/systems/stair/stair-system.tsx"],"names":[],"mappings":"AAuBA,eAAO,MAAM,WAAW,YAgHvB,CAAA"}