@nice2dev/spatial-core 1.0.10

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 (82) hide show
  1. package/README.md +160 -0
  2. package/dist/bim/index.d.ts +366 -0
  3. package/dist/bim/index.d.ts.map +1 -0
  4. package/dist/bim/index.js +60 -0
  5. package/dist/bim/index.js.map +1 -0
  6. package/dist/cad/index.d.ts +329 -0
  7. package/dist/cad/index.d.ts.map +1 -0
  8. package/dist/cad/index.js +124 -0
  9. package/dist/cad/index.js.map +1 -0
  10. package/dist/ecad/index.d.ts +316 -0
  11. package/dist/ecad/index.d.ts.map +1 -0
  12. package/dist/ecad/index.js +11 -0
  13. package/dist/ecad/index.js.map +1 -0
  14. package/dist/export/index.d.ts +93 -0
  15. package/dist/export/index.d.ts.map +1 -0
  16. package/dist/export/index.js +522 -0
  17. package/dist/export/index.js.map +1 -0
  18. package/dist/floor-plan/index.d.ts +248 -0
  19. package/dist/floor-plan/index.d.ts.map +1 -0
  20. package/dist/floor-plan/index.js +228 -0
  21. package/dist/floor-plan/index.js.map +1 -0
  22. package/dist/grid/index.d.ts +160 -0
  23. package/dist/grid/index.d.ts.map +1 -0
  24. package/dist/grid/index.js +319 -0
  25. package/dist/grid/index.js.map +1 -0
  26. package/dist/import/import.worker.d.ts +28 -0
  27. package/dist/import/import.worker.d.ts.map +1 -0
  28. package/dist/import/import.worker.js +52 -0
  29. package/dist/import/import.worker.js.map +1 -0
  30. package/dist/import/index.d.ts +111 -0
  31. package/dist/import/index.d.ts.map +1 -0
  32. package/dist/import/index.js +1092 -0
  33. package/dist/import/index.js.map +1 -0
  34. package/dist/import/workerImport.d.ts +56 -0
  35. package/dist/import/workerImport.d.ts.map +1 -0
  36. package/dist/import/workerImport.js +207 -0
  37. package/dist/import/workerImport.js.map +1 -0
  38. package/dist/index.d.ts +29 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +86 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/interior/index.d.ts +241 -0
  43. package/dist/interior/index.d.ts.map +1 -0
  44. package/dist/interior/index.js +101 -0
  45. package/dist/interior/index.js.map +1 -0
  46. package/dist/measurement/index.d.ts +186 -0
  47. package/dist/measurement/index.d.ts.map +1 -0
  48. package/dist/measurement/index.js +400 -0
  49. package/dist/measurement/index.js.map +1 -0
  50. package/dist/objects/index.d.ts +288 -0
  51. package/dist/objects/index.d.ts.map +1 -0
  52. package/dist/objects/index.js +463 -0
  53. package/dist/objects/index.js.map +1 -0
  54. package/dist/serialization/index.d.ts +421 -0
  55. package/dist/serialization/index.d.ts.map +1 -0
  56. package/dist/serialization/index.js +412 -0
  57. package/dist/serialization/index.js.map +1 -0
  58. package/dist/topology/index.d.ts +252 -0
  59. package/dist/topology/index.d.ts.map +1 -0
  60. package/dist/topology/index.js +525 -0
  61. package/dist/topology/index.js.map +1 -0
  62. package/dist/transitions/index.d.ts +141 -0
  63. package/dist/transitions/index.d.ts.map +1 -0
  64. package/dist/transitions/index.js +160 -0
  65. package/dist/transitions/index.js.map +1 -0
  66. package/dist/unified/index.d.ts +225 -0
  67. package/dist/unified/index.d.ts.map +1 -0
  68. package/dist/unified/index.js +474 -0
  69. package/dist/unified/index.js.map +1 -0
  70. package/dist/virtualization/QuadTree.d.ts +68 -0
  71. package/dist/virtualization/QuadTree.d.ts.map +1 -0
  72. package/dist/virtualization/QuadTree.js +228 -0
  73. package/dist/virtualization/QuadTree.js.map +1 -0
  74. package/dist/virtualization/ViewportCulling.d.ts +92 -0
  75. package/dist/virtualization/ViewportCulling.d.ts.map +1 -0
  76. package/dist/virtualization/ViewportCulling.js +123 -0
  77. package/dist/virtualization/ViewportCulling.js.map +1 -0
  78. package/dist/virtualization/index.d.ts +9 -0
  79. package/dist/virtualization/index.d.ts.map +1 -0
  80. package/dist/virtualization/index.js +9 -0
  81. package/dist/virtualization/index.js.map +1 -0
  82. package/package.json +64 -0
@@ -0,0 +1,228 @@
1
+ /**
2
+ * QuadTree — Spatial indexing for efficient 2D queries
3
+ *
4
+ * Used for viewport culling with large numbers of objects (1000+).
5
+ * Provides O(log n) queries for objects within a rectangular region.
6
+ */
7
+ /** Max items per node before splitting */
8
+ const DEFAULT_MAX_ITEMS = 10;
9
+ /** Max depth to prevent infinite recursion */
10
+ const MAX_DEPTH = 8;
11
+ /**
12
+ * QuadTree for spatial indexing
13
+ */
14
+ export class QuadTree {
15
+ root;
16
+ maxItems;
17
+ itemMap = new Map();
18
+ constructor(bounds, maxItemsPerNode = DEFAULT_MAX_ITEMS) {
19
+ this.root = {
20
+ bounds,
21
+ items: [],
22
+ children: null,
23
+ };
24
+ this.maxItems = maxItemsPerNode;
25
+ }
26
+ /** Insert an item into the quadtree */
27
+ insert(item) {
28
+ this.itemMap.set(item.id, item);
29
+ this.insertIntoNode(this.root, item, 0);
30
+ }
31
+ /** Remove an item by ID */
32
+ remove(id) {
33
+ const item = this.itemMap.get(id);
34
+ if (!item) {
35
+ return false;
36
+ }
37
+ this.itemMap.delete(id);
38
+ return this.removeFromNode(this.root, item);
39
+ }
40
+ /** Update an item's bounds */
41
+ update(id, newBounds) {
42
+ const item = this.itemMap.get(id);
43
+ if (!item) {
44
+ return false;
45
+ }
46
+ this.remove(id);
47
+ item.bounds = newBounds;
48
+ this.insert(item);
49
+ return true;
50
+ }
51
+ /** Query all items intersecting with the given bounds */
52
+ query(bounds) {
53
+ const results = [];
54
+ this.queryNode(this.root, bounds, results);
55
+ return results;
56
+ }
57
+ /** Get all items */
58
+ getAll() {
59
+ return Array.from(this.itemMap.values());
60
+ }
61
+ /** Get item by ID */
62
+ get(id) {
63
+ return this.itemMap.get(id);
64
+ }
65
+ /** Get total item count */
66
+ get size() {
67
+ return this.itemMap.size;
68
+ }
69
+ /** Clear all items */
70
+ clear() {
71
+ this.itemMap.clear();
72
+ this.root.items = [];
73
+ this.root.children = null;
74
+ }
75
+ /** Rebuild the quadtree (useful after many removes) */
76
+ rebuild() {
77
+ const allItems = Array.from(this.itemMap.values());
78
+ this.root.items = [];
79
+ this.root.children = null;
80
+ for (const item of allItems) {
81
+ this.insertIntoNode(this.root, item, 0);
82
+ }
83
+ }
84
+ // ══════════════════════════════════════════════════════════════
85
+ // Private methods
86
+ // ══════════════════════════════════════════════════════════════
87
+ insertIntoNode(node, item, depth) {
88
+ // If node has children, try to insert into a child
89
+ if (node.children) {
90
+ const childIndex = this.getChildIndex(node, item.bounds);
91
+ if (childIndex !== -1) {
92
+ this.insertIntoNode(node.children[childIndex], item, depth + 1);
93
+ return;
94
+ }
95
+ // Item spans multiple quadrants, store in this node
96
+ node.items.push(item);
97
+ return;
98
+ }
99
+ // Add to this node
100
+ node.items.push(item);
101
+ // Split if needed and not at max depth
102
+ if (node.items.length > this.maxItems && depth < MAX_DEPTH) {
103
+ this.split(node);
104
+ // Re-insert items into children
105
+ const itemsToReinsert = [...node.items];
106
+ node.items = [];
107
+ for (const i of itemsToReinsert) {
108
+ this.insertIntoNode(node, i, depth);
109
+ }
110
+ }
111
+ }
112
+ removeFromNode(node, item) {
113
+ // Check this node's items
114
+ const idx = node.items.findIndex((i) => i.id === item.id);
115
+ if (idx !== -1) {
116
+ node.items.splice(idx, 1);
117
+ return true;
118
+ }
119
+ // Check children
120
+ if (node.children) {
121
+ for (const child of node.children) {
122
+ if (this.boundsIntersect(child.bounds, item.bounds)) {
123
+ if (this.removeFromNode(child, item)) {
124
+ return true;
125
+ }
126
+ }
127
+ }
128
+ }
129
+ return false;
130
+ }
131
+ queryNode(node, bounds, results) {
132
+ // Check items in this node
133
+ for (const item of node.items) {
134
+ if (this.boundsIntersect(item.bounds, bounds)) {
135
+ results.push(item);
136
+ }
137
+ }
138
+ // Check children
139
+ if (node.children) {
140
+ for (const child of node.children) {
141
+ if (this.boundsIntersect(child.bounds, bounds)) {
142
+ this.queryNode(child, bounds, results);
143
+ }
144
+ }
145
+ }
146
+ }
147
+ split(node) {
148
+ const { x, y, width, height } = node.bounds;
149
+ const hw = width / 2;
150
+ const hh = height / 2;
151
+ node.children = [
152
+ { bounds: { x, y, width: hw, height: hh }, items: [], children: null }, // NW
153
+ { bounds: { x: x + hw, y, width: hw, height: hh }, items: [], children: null }, // NE
154
+ { bounds: { x, y: y + hh, width: hw, height: hh }, items: [], children: null }, // SW
155
+ { bounds: { x: x + hw, y: y + hh, width: hw, height: hh }, items: [], children: null }, // SE
156
+ ];
157
+ }
158
+ getChildIndex(node, bounds) {
159
+ if (!node.children) {
160
+ return -1;
161
+ }
162
+ const midX = node.bounds.x + node.bounds.width / 2;
163
+ const midY = node.bounds.y + node.bounds.height / 2;
164
+ const inLeft = bounds.x + bounds.width <= midX;
165
+ const inRight = bounds.x >= midX;
166
+ const inTop = bounds.y + bounds.height <= midY;
167
+ const inBottom = bounds.y >= midY;
168
+ if (inTop && inLeft) {
169
+ return 0;
170
+ } // NW
171
+ if (inTop && inRight) {
172
+ return 1;
173
+ } // NE
174
+ if (inBottom && inLeft) {
175
+ return 2;
176
+ } // SW
177
+ if (inBottom && inRight) {
178
+ return 3;
179
+ } // SE
180
+ return -1; // Spans multiple quadrants
181
+ }
182
+ boundsIntersect(a, b) {
183
+ return (a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y);
184
+ }
185
+ }
186
+ /**
187
+ * Create a QuadTree for a floor plan with automatic bounds detection.
188
+ */
189
+ export function createFloorPlanQuadTree(items, padding = 100) {
190
+ // Calculate bounds from all items
191
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
192
+ for (const item of items) {
193
+ const { x, y } = item.position;
194
+ const { width = 20, height = 20 } = item.size ?? {};
195
+ minX = Math.min(minX, x - width / 2);
196
+ minY = Math.min(minY, y - height / 2);
197
+ maxX = Math.max(maxX, x + width / 2);
198
+ maxY = Math.max(maxY, y + height / 2);
199
+ }
200
+ // Handle empty items
201
+ if (!Number.isFinite(minX)) {
202
+ minX = minY = 0;
203
+ maxX = maxY = 1000;
204
+ }
205
+ const bounds = {
206
+ x: minX - padding,
207
+ y: minY - padding,
208
+ width: maxX - minX + padding * 2,
209
+ height: maxY - minY + padding * 2,
210
+ };
211
+ const quadTree = new QuadTree(bounds);
212
+ for (const item of items) {
213
+ const { x, y } = item.position;
214
+ const { width = 20, height = 20 } = item.size ?? {};
215
+ quadTree.insert({
216
+ id: item.id,
217
+ bounds: {
218
+ x: x - width / 2,
219
+ y: y - height / 2,
220
+ width,
221
+ height,
222
+ },
223
+ data: item.data,
224
+ });
225
+ }
226
+ return quadTree;
227
+ }
228
+ //# sourceMappingURL=QuadTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuadTree.js","sourceRoot":"","sources":["../../src/virtualization/QuadTree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * ViewportCulling — Utilities for efficient viewport-based rendering
3
+ *
4
+ * Calculates visible bounds and filters objects for rendering optimization.
5
+ */
6
+ import type { Bounds, QuadTree, QuadTreeItem } from './QuadTree';
7
+ /** Viewport state with pan/zoom */
8
+ export interface ViewportState {
9
+ /** Current zoom level (1 = 100%) */
10
+ zoom: number;
11
+ /** Pan offset in screen coordinates */
12
+ pan: {
13
+ x: number;
14
+ y: number;
15
+ };
16
+ }
17
+ /** Container size in pixels */
18
+ export interface ContainerSize {
19
+ width: number;
20
+ height: number;
21
+ }
22
+ /**
23
+ * Calculate visible world bounds from viewport state.
24
+ *
25
+ * @param viewport - Current viewport pan/zoom state
26
+ * @param containerSize - Container dimensions in pixels
27
+ * @param overscan - Extra margin to render outside visible area (default 100px)
28
+ * @returns World-space bounds of the visible area
29
+ */
30
+ export declare function calculateVisibleBounds(viewport: ViewportState, containerSize: ContainerSize, overscan?: number): Bounds;
31
+ /**
32
+ * Check if an object's bounds are within the visible viewport.
33
+ *
34
+ * @param objectBounds - Object bounds in world coordinates
35
+ * @param visibleBounds - Visible area bounds in world coordinates
36
+ * @returns true if the object should be rendered
37
+ */
38
+ export declare function isInViewport(objectBounds: Bounds, visibleBounds: Bounds): boolean;
39
+ /**
40
+ * Filter items to only those visible in the viewport.
41
+ *
42
+ * @param items - Array of items with position and optional size
43
+ * @param visibleBounds - Visible bounds in world coordinates
44
+ * @returns Filtered array of visible items
45
+ */
46
+ export declare function filterVisibleItems<T extends {
47
+ position: {
48
+ x: number;
49
+ y: number;
50
+ };
51
+ size?: {
52
+ width: number;
53
+ height: number;
54
+ };
55
+ }>(items: T[], visibleBounds: Bounds): T[];
56
+ /**
57
+ * Query visible items from a QuadTree based on viewport.
58
+ *
59
+ * @param quadTree - QuadTree spatial index
60
+ * @param viewport - Current viewport state
61
+ * @param containerSize - Container dimensions
62
+ * @param overscan - Extra margin to render
63
+ * @returns Array of visible items from the quadtree
64
+ */
65
+ export declare function queryVisibleFromQuadTree<T>(quadTree: QuadTree<T>, viewport: ViewportState, containerSize: ContainerSize, overscan?: number): QuadTreeItem<T>[];
66
+ /**
67
+ * Calculate if virtual rendering is beneficial based on object count.
68
+ *
69
+ * @param totalObjects - Total number of objects in the scene
70
+ * @param threshold - Minimum objects for virtual rendering (default 200)
71
+ * @returns true if virtual rendering should be used
72
+ */
73
+ export declare function shouldUseVirtualRendering(totalObjects: number, threshold?: number): boolean;
74
+ /**
75
+ * Calculate rendering statistics for debugging/monitoring.
76
+ */
77
+ export declare function calculateRenderStats(totalObjects: number, visibleObjects: number, viewport: ViewportState): {
78
+ total: number;
79
+ visible: number;
80
+ culled: number;
81
+ cullPercentage: number;
82
+ zoom: number;
83
+ };
84
+ /**
85
+ * Debounced quadtree update for dynamic scenes.
86
+ * Returns a function that batches updates.
87
+ */
88
+ export declare function createQuadTreeUpdater<T>(quadTree: QuadTree<T>, debounceMs?: number): {
89
+ scheduleUpdate: (id: string, bounds: Bounds) => void;
90
+ flush: () => void;
91
+ };
92
+ //# sourceMappingURL=ViewportCulling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ViewportCulling.d.ts","sourceRoot":"","sources":["../../src/virtualization/ViewportCulling.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEjE,mCAAmC;AACnC,MAAM,WAAW,aAAa;IAC5B,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,GAAG,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/B;AAED,+BAA+B;AAC/B,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,aAAa,EACvB,aAAa,EAAE,aAAa,EAC5B,QAAQ,SAAM,GACb,MAAM,CAgBR;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAOjF;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,CAAC,SAAS;IAAE,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAC1F,KAAK,EAAE,CAAC,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,CAAC,EAAE,CAYxC;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EACxC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EACrB,QAAQ,EAAE,aAAa,EACvB,aAAa,EAAE,aAAa,EAC5B,QAAQ,SAAM,GACb,YAAY,CAAC,CAAC,CAAC,EAAE,CAGnB;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG,OAAO,CAExF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,aAAa,GACtB;IACD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,CASA;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EACrB,UAAU,SAAK,GACd;IACD,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAuBA"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * ViewportCulling — Utilities for efficient viewport-based rendering
3
+ *
4
+ * Calculates visible bounds and filters objects for rendering optimization.
5
+ */
6
+ /**
7
+ * Calculate visible world bounds from viewport state.
8
+ *
9
+ * @param viewport - Current viewport pan/zoom state
10
+ * @param containerSize - Container dimensions in pixels
11
+ * @param overscan - Extra margin to render outside visible area (default 100px)
12
+ * @returns World-space bounds of the visible area
13
+ */
14
+ export function calculateVisibleBounds(viewport, containerSize, overscan = 100) {
15
+ // Convert screen coordinates to world coordinates
16
+ // Screen origin is at pan.x, pan.y after zoom
17
+ // World coord = (screen - pan) / zoom
18
+ const worldWidth = (containerSize.width + overscan * 2) / viewport.zoom;
19
+ const worldHeight = (containerSize.height + overscan * 2) / viewport.zoom;
20
+ const worldX = (-viewport.pan.x - overscan) / viewport.zoom;
21
+ const worldY = (-viewport.pan.y - overscan) / viewport.zoom;
22
+ return {
23
+ x: worldX,
24
+ y: worldY,
25
+ width: worldWidth,
26
+ height: worldHeight,
27
+ };
28
+ }
29
+ /**
30
+ * Check if an object's bounds are within the visible viewport.
31
+ *
32
+ * @param objectBounds - Object bounds in world coordinates
33
+ * @param visibleBounds - Visible area bounds in world coordinates
34
+ * @returns true if the object should be rendered
35
+ */
36
+ export function isInViewport(objectBounds, visibleBounds) {
37
+ return (objectBounds.x < visibleBounds.x + visibleBounds.width &&
38
+ objectBounds.x + objectBounds.width > visibleBounds.x &&
39
+ objectBounds.y < visibleBounds.y + visibleBounds.height &&
40
+ objectBounds.y + objectBounds.height > visibleBounds.y);
41
+ }
42
+ /**
43
+ * Filter items to only those visible in the viewport.
44
+ *
45
+ * @param items - Array of items with position and optional size
46
+ * @param visibleBounds - Visible bounds in world coordinates
47
+ * @returns Filtered array of visible items
48
+ */
49
+ export function filterVisibleItems(items, visibleBounds) {
50
+ return items.filter((item) => {
51
+ const { x, y } = item.position;
52
+ const { width = 20, height = 20 } = item.size ?? {};
53
+ const bounds = {
54
+ x: x - width / 2,
55
+ y: y - height / 2,
56
+ width,
57
+ height,
58
+ };
59
+ return isInViewport(bounds, visibleBounds);
60
+ });
61
+ }
62
+ /**
63
+ * Query visible items from a QuadTree based on viewport.
64
+ *
65
+ * @param quadTree - QuadTree spatial index
66
+ * @param viewport - Current viewport state
67
+ * @param containerSize - Container dimensions
68
+ * @param overscan - Extra margin to render
69
+ * @returns Array of visible items from the quadtree
70
+ */
71
+ export function queryVisibleFromQuadTree(quadTree, viewport, containerSize, overscan = 100) {
72
+ const visibleBounds = calculateVisibleBounds(viewport, containerSize, overscan);
73
+ return quadTree.query(visibleBounds);
74
+ }
75
+ /**
76
+ * Calculate if virtual rendering is beneficial based on object count.
77
+ *
78
+ * @param totalObjects - Total number of objects in the scene
79
+ * @param threshold - Minimum objects for virtual rendering (default 200)
80
+ * @returns true if virtual rendering should be used
81
+ */
82
+ export function shouldUseVirtualRendering(totalObjects, threshold = 200) {
83
+ return totalObjects >= threshold;
84
+ }
85
+ /**
86
+ * Calculate rendering statistics for debugging/monitoring.
87
+ */
88
+ export function calculateRenderStats(totalObjects, visibleObjects, viewport) {
89
+ const culled = totalObjects - visibleObjects;
90
+ return {
91
+ total: totalObjects,
92
+ visible: visibleObjects,
93
+ culled,
94
+ cullPercentage: totalObjects > 0 ? Math.round((culled / totalObjects) * 100) : 0,
95
+ zoom: viewport.zoom,
96
+ };
97
+ }
98
+ /**
99
+ * Debounced quadtree update for dynamic scenes.
100
+ * Returns a function that batches updates.
101
+ */
102
+ export function createQuadTreeUpdater(quadTree, debounceMs = 16) {
103
+ const pendingUpdates = new Map();
104
+ let timeoutId = null;
105
+ const flush = () => {
106
+ if (pendingUpdates.size === 0) {
107
+ return;
108
+ }
109
+ for (const [id, bounds] of pendingUpdates) {
110
+ quadTree.update(id, bounds);
111
+ }
112
+ pendingUpdates.clear();
113
+ timeoutId = null;
114
+ };
115
+ const scheduleUpdate = (id, bounds) => {
116
+ pendingUpdates.set(id, bounds);
117
+ if (!timeoutId) {
118
+ timeoutId = setTimeout(flush, debounceMs);
119
+ }
120
+ };
121
+ return { scheduleUpdate, flush };
122
+ }
123
+ //# sourceMappingURL=ViewportCulling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ViewportCulling.js","sourceRoot":"","sources":["../../src/virtualization/ViewportCulling.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Virtualization — Efficient rendering for large floor plans
3
+ *
4
+ * Provides spatial indexing (QuadTree) and viewport culling utilities
5
+ * for rendering optimization with 1000+ objects.
6
+ */
7
+ export { QuadTree, createFloorPlanQuadTree, type Bounds, type QuadTreeItem, } from './QuadTree';
8
+ export { calculateVisibleBounds, isInViewport, filterVisibleItems, queryVisibleFromQuadTree, shouldUseVirtualRendering, calculateRenderStats, createQuadTreeUpdater, type ViewportState, type ContainerSize, } from './ViewportCulling';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/virtualization/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACH,QAAQ,EACR,uBAAuB,EACvB,KAAK,MAAM,EACX,KAAK,YAAY,GACpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACH,sBAAsB,EACtB,YAAY,EACZ,kBAAkB,EAClB,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,aAAa,GACrB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Virtualization — Efficient rendering for large floor plans
3
+ *
4
+ * Provides spatial indexing (QuadTree) and viewport culling utilities
5
+ * for rendering optimization with 1000+ objects.
6
+ */
7
+ export { QuadTree, createFloorPlanQuadTree, } from './QuadTree';
8
+ export { calculateVisibleBounds, isInViewport, filterVisibleItems, queryVisibleFromQuadTree, shouldUseVirtualRendering, calculateRenderStats, createQuadTreeUpdater, } from './ViewportCulling';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/virtualization/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACH,QAAQ,EACR,uBAAuB,GAG1B,MAAM,YAAY,CAAC;AAEpB,OAAO,EACH,sBAAsB,EACtB,YAAY,EACZ,kBAAkB,EAClB,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,GAGxB,MAAM,mBAAmB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@nice2dev/spatial-core",
3
+ "version": "1.0.10",
4
+ "description": "Unified spatial/floor-plan/CAD core logic for Nice2Dev UI components",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ },
14
+ "./grid": {
15
+ "import": "./dist/grid/index.js",
16
+ "types": "./dist/grid/index.d.ts"
17
+ },
18
+ "./objects": {
19
+ "import": "./dist/objects/index.js",
20
+ "types": "./dist/objects/index.d.ts"
21
+ },
22
+ "./floor-plan": {
23
+ "import": "./dist/floor-plan/index.js",
24
+ "types": "./dist/floor-plan/index.d.ts"
25
+ },
26
+ "./measurement": {
27
+ "import": "./dist/measurement/index.js",
28
+ "types": "./dist/measurement/index.d.ts"
29
+ },
30
+ "./serialization": {
31
+ "import": "./dist/serialization/index.js",
32
+ "types": "./dist/serialization/index.d.ts"
33
+ }
34
+ },
35
+ "files": [
36
+ "dist",
37
+ "README.md"
38
+ ],
39
+ "scripts": {
40
+ "build": "tsc -p tsconfig.build.json",
41
+ "dev": "tsc -p tsconfig.build.json --watch",
42
+ "test": "vitest run",
43
+ "test:watch": "vitest",
44
+ "lint": "eslint src --ext .ts",
45
+ "clean": "rimraf dist"
46
+ },
47
+ "keywords": [
48
+ "spatial",
49
+ "floor-plan",
50
+ "cad",
51
+ "grid",
52
+ "editor",
53
+ "nice2dev"
54
+ ],
55
+ "author": "NiceToDev",
56
+ "license": "SEE LICENSE IN LICENSE",
57
+ "devDependencies": {
58
+ "typescript": "^5.3.0",
59
+ "vitest": "^1.2.0",
60
+ "rimraf": "^5.0.0"
61
+ },
62
+ "peerDependencies": {},
63
+ "sideEffects": false
64
+ }