@ifc-lite/renderer 1.1.7 → 1.2.1
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/LICENSE +373 -0
- package/dist/bvh.d.ts +50 -0
- package/dist/bvh.d.ts.map +1 -0
- package/dist/bvh.js +177 -0
- package/dist/bvh.js.map +1 -0
- package/dist/camera.d.ts +17 -0
- package/dist/camera.d.ts.map +1 -1
- package/dist/camera.js +72 -6
- package/dist/camera.js.map +1 -1
- package/dist/index.d.ts +51 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +587 -125
- package/dist/index.js.map +1 -1
- package/dist/math.d.ts +30 -0
- package/dist/math.d.ts.map +1 -1
- package/dist/math.js +103 -0
- package/dist/math.js.map +1 -1
- package/dist/picker.js +2 -2
- package/dist/picker.js.map +1 -1
- package/dist/pipeline.d.ts +17 -0
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +351 -49
- package/dist/pipeline.js.map +1 -1
- package/dist/raycaster.d.ts +67 -0
- package/dist/raycaster.d.ts.map +1 -0
- package/dist/raycaster.js +192 -0
- package/dist/raycaster.js.map +1 -0
- package/dist/scene.d.ts +56 -2
- package/dist/scene.d.ts.map +1 -1
- package/dist/scene.js +362 -26
- package/dist/scene.js.map +1 -1
- package/dist/section-plane.d.ts +14 -4
- package/dist/section-plane.d.ts.map +1 -1
- package/dist/section-plane.js +129 -53
- package/dist/section-plane.js.map +1 -1
- package/dist/snap-detector.d.ts +119 -0
- package/dist/snap-detector.d.ts.map +1 -0
- package/dist/snap-detector.js +706 -0
- package/dist/snap-detector.js.map +1 -0
- package/dist/types.d.ts +14 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/zero-copy-uploader.d.ts +145 -0
- package/dist/zero-copy-uploader.d.ts.map +1 -0
- package/dist/zero-copy-uploader.js +146 -0
- package/dist/zero-copy-uploader.js.map +1 -0
- package/package.json +11 -10
package/dist/section-plane.js
CHANGED
|
@@ -3,19 +3,37 @@
|
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
4
|
export class SectionPlaneRenderer {
|
|
5
5
|
device;
|
|
6
|
-
|
|
6
|
+
bindGroupLayout = null; // Shared layout for both pipelines
|
|
7
|
+
previewPipeline = null; // With depth test (respects geometry)
|
|
8
|
+
cutPipeline = null; // No depth test (always visible)
|
|
7
9
|
vertexBuffer = null;
|
|
8
10
|
uniformBuffer = null;
|
|
9
11
|
bindGroup = null;
|
|
10
12
|
format;
|
|
13
|
+
sampleCount;
|
|
11
14
|
initialized = false;
|
|
12
|
-
constructor(device, format) {
|
|
15
|
+
constructor(device, format, sampleCount = 4) {
|
|
13
16
|
this.device = device;
|
|
14
17
|
this.format = format;
|
|
18
|
+
this.sampleCount = sampleCount;
|
|
15
19
|
}
|
|
16
20
|
init() {
|
|
17
21
|
if (this.initialized)
|
|
18
22
|
return;
|
|
23
|
+
// Create explicit bind group layout (shared between both pipelines)
|
|
24
|
+
this.bindGroupLayout = this.device.createBindGroupLayout({
|
|
25
|
+
entries: [
|
|
26
|
+
{
|
|
27
|
+
binding: 0,
|
|
28
|
+
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
29
|
+
buffer: { type: 'uniform' },
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
});
|
|
33
|
+
// Create pipeline layout using the shared bind group layout
|
|
34
|
+
const pipelineLayout = this.device.createPipelineLayout({
|
|
35
|
+
bindGroupLayouts: [this.bindGroupLayout],
|
|
36
|
+
});
|
|
19
37
|
// Create shader for section plane rendering
|
|
20
38
|
const shaderModule = this.device.createShaderModule({
|
|
21
39
|
code: `
|
|
@@ -40,33 +58,59 @@ export class SectionPlaneRenderer {
|
|
|
40
58
|
|
|
41
59
|
@fragment
|
|
42
60
|
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
43
|
-
// Create
|
|
44
|
-
let gridSize = 0.
|
|
45
|
-
let lineWidth = 0.
|
|
61
|
+
// Create fine grid pattern
|
|
62
|
+
let gridSize = 0.01; // Fine grid cells (100 divisions)
|
|
63
|
+
let lineWidth = 0.001; // Very thin lines
|
|
64
|
+
let majorGridSize = 0.1; // Major grid every 10 cells
|
|
65
|
+
let majorLineWidth = 0.002; // Slightly thicker major lines
|
|
46
66
|
|
|
67
|
+
// Minor grid
|
|
47
68
|
let gridX = abs(fract(input.uv.x / gridSize + 0.5) - 0.5);
|
|
48
69
|
let gridY = abs(fract(input.uv.y / gridSize + 0.5) - 0.5);
|
|
70
|
+
let isMinorGridLine = min(gridX, gridY) < lineWidth;
|
|
71
|
+
|
|
72
|
+
// Major grid (every 10 cells)
|
|
73
|
+
let majorX = abs(fract(input.uv.x / majorGridSize + 0.5) - 0.5);
|
|
74
|
+
let majorY = abs(fract(input.uv.y / majorGridSize + 0.5) - 0.5);
|
|
75
|
+
let isMajorGridLine = min(majorX, majorY) < majorLineWidth;
|
|
49
76
|
|
|
50
|
-
|
|
51
|
-
let
|
|
77
|
+
// Soft edge fade
|
|
78
|
+
let edgeDist = min(input.uv.x, min(input.uv.y, min(1.0 - input.uv.x, 1.0 - input.uv.y)));
|
|
79
|
+
let edgeFade = smoothstep(0.0, 0.08, edgeDist);
|
|
52
80
|
|
|
53
|
-
//
|
|
54
|
-
let
|
|
81
|
+
// Subtle border
|
|
82
|
+
let borderGlow = 1.0 - smoothstep(0.0, 0.03, edgeDist);
|
|
55
83
|
|
|
56
84
|
var color = uniforms.planeColor;
|
|
57
|
-
|
|
58
|
-
|
|
85
|
+
|
|
86
|
+
// Layered rendering: base fill + minor grid + major grid + border
|
|
87
|
+
if (isMajorGridLine) {
|
|
88
|
+
// Major grid lines - subtle white
|
|
89
|
+
color = vec4<f32>(1.0, 1.0, 1.0, color.a * 1.5);
|
|
90
|
+
} else if (isMinorGridLine) {
|
|
91
|
+
// Minor grid lines - slightly brighter
|
|
92
|
+
color = vec4<f32>(color.rgb * 1.3, color.a * 1.2);
|
|
59
93
|
}
|
|
60
94
|
|
|
95
|
+
// Add subtle border
|
|
96
|
+
color = vec4<f32>(
|
|
97
|
+
mix(color.rgb, vec3<f32>(1.0, 1.0, 1.0), borderGlow * 0.3),
|
|
98
|
+
color.a + borderGlow * 0.2
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
// Apply edge fade
|
|
61
102
|
color.a *= edgeFade;
|
|
62
103
|
|
|
104
|
+
// Clamp alpha
|
|
105
|
+
color.a = min(color.a, 0.5);
|
|
106
|
+
|
|
63
107
|
return color;
|
|
64
108
|
}
|
|
65
109
|
`,
|
|
66
110
|
});
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
layout:
|
|
111
|
+
// Shared pipeline config (now using explicit layout)
|
|
112
|
+
const pipelineBase = {
|
|
113
|
+
layout: pipelineLayout,
|
|
70
114
|
vertex: {
|
|
71
115
|
module: shaderModule,
|
|
72
116
|
entryPoint: 'vs_main',
|
|
@@ -103,10 +147,26 @@ export class SectionPlaneRenderer {
|
|
|
103
147
|
topology: 'triangle-list',
|
|
104
148
|
cullMode: 'none',
|
|
105
149
|
},
|
|
150
|
+
multisample: {
|
|
151
|
+
count: this.sampleCount,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
// Preview pipeline: only draw where there's NO geometry (behind/around building)
|
|
155
|
+
this.previewPipeline = this.device.createRenderPipeline({
|
|
156
|
+
...pipelineBase,
|
|
106
157
|
depthStencil: {
|
|
107
158
|
format: 'depth24plus',
|
|
108
|
-
depthWriteEnabled: false,
|
|
109
|
-
depthCompare: '
|
|
159
|
+
depthWriteEnabled: false,
|
|
160
|
+
depthCompare: 'greater', // Only draw where plane is behind geometry (empty space)
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
// Cut pipeline: always visible (shows where the cut is)
|
|
164
|
+
this.cutPipeline = this.device.createRenderPipeline({
|
|
165
|
+
...pipelineBase,
|
|
166
|
+
depthStencil: {
|
|
167
|
+
format: 'depth24plus',
|
|
168
|
+
depthWriteEnabled: false,
|
|
169
|
+
depthCompare: 'always', // Always draw on top
|
|
110
170
|
},
|
|
111
171
|
});
|
|
112
172
|
// Create vertex buffer (6 vertices for 2 triangles)
|
|
@@ -119,67 +179,81 @@ export class SectionPlaneRenderer {
|
|
|
119
179
|
size: 80, // mat4x4 (64) + vec4 (16) = 80 bytes
|
|
120
180
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
121
181
|
});
|
|
122
|
-
// Create bind group
|
|
182
|
+
// Create bind group using explicit layout (compatible with both pipelines)
|
|
123
183
|
this.bindGroup = this.device.createBindGroup({
|
|
124
|
-
layout: this.
|
|
184
|
+
layout: this.bindGroupLayout,
|
|
125
185
|
entries: [
|
|
126
186
|
{ binding: 0, resource: { buffer: this.uniformBuffer } },
|
|
127
187
|
],
|
|
128
188
|
});
|
|
129
189
|
this.initialized = true;
|
|
130
190
|
}
|
|
131
|
-
|
|
191
|
+
/**
|
|
192
|
+
* Draw section plane into an existing render pass (preferred - avoids MSAA mismatch)
|
|
193
|
+
*/
|
|
194
|
+
draw(pass, options) {
|
|
132
195
|
this.init();
|
|
133
|
-
if (!this.
|
|
196
|
+
if (!this.previewPipeline || !this.cutPipeline || !this.vertexBuffer || !this.uniformBuffer || !this.bindGroup) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const { axis, position, bounds, viewProj, isPreview, min: minOverride, max: maxOverride } = options;
|
|
200
|
+
// Only draw section plane in preview mode - hide it during active cutting
|
|
201
|
+
if (!isPreview) {
|
|
134
202
|
return;
|
|
135
203
|
}
|
|
136
|
-
const { axis, position, bounds, viewProj } = options;
|
|
137
204
|
// Calculate plane vertices based on axis and bounds
|
|
138
|
-
const vertices = this.calculatePlaneVertices(axis, position, bounds);
|
|
205
|
+
const vertices = this.calculatePlaneVertices(axis, position, bounds, 0, minOverride, maxOverride);
|
|
139
206
|
this.device.queue.writeBuffer(this.vertexBuffer, 0, vertices);
|
|
140
207
|
// Update uniforms
|
|
141
208
|
const uniforms = new Float32Array(20);
|
|
142
209
|
uniforms.set(viewProj, 0);
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
210
|
+
// Axis-specific colors for better identification
|
|
211
|
+
// down (Y) = light blue, front (Z) = green, side (X) = orange
|
|
212
|
+
if (axis === 'down') {
|
|
213
|
+
uniforms[16] = 0.012; // R - #03A9F4
|
|
214
|
+
uniforms[17] = 0.663; // G
|
|
215
|
+
uniforms[18] = 0.957; // B
|
|
216
|
+
}
|
|
217
|
+
else if (axis === 'front') {
|
|
218
|
+
uniforms[16] = 0.298; // R - #4CAF50
|
|
219
|
+
uniforms[17] = 0.686; // G
|
|
220
|
+
uniforms[18] = 0.314; // B
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
uniforms[16] = 1.0; // R - #FF9800
|
|
224
|
+
uniforms[17] = 0.596; // G
|
|
225
|
+
uniforms[18] = 0.0; // B
|
|
226
|
+
}
|
|
227
|
+
// Preview mode opacity
|
|
228
|
+
uniforms[19] = 0.25;
|
|
148
229
|
this.device.queue.writeBuffer(this.uniformBuffer, 0, uniforms);
|
|
149
|
-
//
|
|
150
|
-
|
|
151
|
-
colorAttachments: [{
|
|
152
|
-
view: textureView,
|
|
153
|
-
loadOp: 'load', // Keep existing content
|
|
154
|
-
storeOp: 'store',
|
|
155
|
-
}],
|
|
156
|
-
depthStencilAttachment: {
|
|
157
|
-
view: depthView,
|
|
158
|
-
depthLoadOp: 'load',
|
|
159
|
-
depthStoreOp: 'store',
|
|
160
|
-
},
|
|
161
|
-
});
|
|
162
|
-
pass.setPipeline(this.pipeline);
|
|
230
|
+
// Draw section plane with preview pipeline (respects depth)
|
|
231
|
+
pass.setPipeline(this.previewPipeline);
|
|
163
232
|
pass.setBindGroup(0, this.bindGroup);
|
|
164
233
|
pass.setVertexBuffer(0, this.vertexBuffer);
|
|
165
234
|
pass.draw(6); // 2 triangles
|
|
166
|
-
pass.end();
|
|
167
235
|
}
|
|
168
|
-
calculatePlaneVertices(axis, position, bounds
|
|
236
|
+
calculatePlaneVertices(axis, position, bounds, inset = 0, // 0 = full size, 0.15 = 15% smaller on each side
|
|
237
|
+
minOverride, maxOverride) {
|
|
169
238
|
const { min, max } = bounds;
|
|
170
|
-
//
|
|
171
|
-
const
|
|
172
|
-
const
|
|
173
|
-
const
|
|
174
|
-
const
|
|
239
|
+
// Calculate base size with 10% padding for preview
|
|
240
|
+
const basePadding = 0.1;
|
|
241
|
+
const effectiveScale = (1 + basePadding) * (1 - inset * 2);
|
|
242
|
+
const sizeX = (max.x - min.x) * effectiveScale;
|
|
243
|
+
const sizeY = (max.y - min.y) * effectiveScale;
|
|
244
|
+
const sizeZ = (max.z - min.z) * effectiveScale;
|
|
175
245
|
const centerX = (min.x + max.x) / 2;
|
|
176
246
|
const centerY = (min.y + max.y) / 2;
|
|
177
247
|
const centerZ = (min.z + max.z) / 2;
|
|
178
248
|
// Calculate the plane position along the axis
|
|
179
249
|
const t = position / 100;
|
|
250
|
+
const axisIdx = axis === 'side' ? 'x' : axis === 'down' ? 'y' : 'z';
|
|
251
|
+
const axisMin = minOverride ?? min[axisIdx];
|
|
252
|
+
const axisMax = maxOverride ?? max[axisIdx];
|
|
180
253
|
let vertices = [];
|
|
181
|
-
if (axis === '
|
|
182
|
-
|
|
254
|
+
if (axis === 'side') {
|
|
255
|
+
// Side = X axis (YZ plane)
|
|
256
|
+
const x = axisMin + t * (axisMax - axisMin);
|
|
183
257
|
const halfY = sizeY / 2;
|
|
184
258
|
const halfZ = sizeZ / 2;
|
|
185
259
|
// Quad facing X axis (vertices in YZ plane)
|
|
@@ -194,8 +268,9 @@ export class SectionPlaneRenderer {
|
|
|
194
268
|
x, centerY - halfY, centerZ + halfZ, 0, 1,
|
|
195
269
|
];
|
|
196
270
|
}
|
|
197
|
-
else if (axis === '
|
|
198
|
-
|
|
271
|
+
else if (axis === 'down') {
|
|
272
|
+
// Down = Y axis (XZ plane) - horizontal cut
|
|
273
|
+
const y = axisMin + t * (axisMax - axisMin);
|
|
199
274
|
const halfX = sizeX / 2;
|
|
200
275
|
const halfZ = sizeZ / 2;
|
|
201
276
|
// Quad facing Y axis (vertices in XZ plane)
|
|
@@ -211,7 +286,8 @@ export class SectionPlaneRenderer {
|
|
|
211
286
|
];
|
|
212
287
|
}
|
|
213
288
|
else {
|
|
214
|
-
|
|
289
|
+
// Front = Z axis (XY plane)
|
|
290
|
+
const z = axisMin + t * (axisMax - axisMin);
|
|
215
291
|
const halfX = sizeX / 2;
|
|
216
292
|
const halfY = sizeY / 2;
|
|
217
293
|
// Quad facing Z axis (vertices in XY plane)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section-plane.js","sourceRoot":"","sources":["../src/section-plane.ts"],"names":[],"mappings":"AAAA;;+DAE+D;
|
|
1
|
+
{"version":3,"file":"section-plane.js","sourceRoot":"","sources":["../src/section-plane.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { MeshData } from '@ifc-lite/geometry';
|
|
2
|
+
import type { Ray, Vec3, Intersection } from './raycaster';
|
|
3
|
+
export declare enum SnapType {
|
|
4
|
+
VERTEX = "vertex",
|
|
5
|
+
EDGE = "edge",
|
|
6
|
+
FACE = "face",
|
|
7
|
+
FACE_CENTER = "face_center"
|
|
8
|
+
}
|
|
9
|
+
export interface SnapTarget {
|
|
10
|
+
type: SnapType;
|
|
11
|
+
position: Vec3;
|
|
12
|
+
normal?: Vec3;
|
|
13
|
+
expressId: number;
|
|
14
|
+
confidence: number;
|
|
15
|
+
metadata?: {
|
|
16
|
+
vertices?: Vec3[];
|
|
17
|
+
edgeIndex?: number;
|
|
18
|
+
faceIndex?: number;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export interface SnapOptions {
|
|
22
|
+
snapToVertices: boolean;
|
|
23
|
+
snapToEdges: boolean;
|
|
24
|
+
snapToFaces: boolean;
|
|
25
|
+
snapRadius: number;
|
|
26
|
+
screenSnapRadius: number;
|
|
27
|
+
}
|
|
28
|
+
export interface EdgeLockInput {
|
|
29
|
+
edge: {
|
|
30
|
+
v0: Vec3;
|
|
31
|
+
v1: Vec3;
|
|
32
|
+
} | null;
|
|
33
|
+
meshExpressId: number | null;
|
|
34
|
+
lockStrength: number;
|
|
35
|
+
}
|
|
36
|
+
export interface MagneticSnapResult {
|
|
37
|
+
snapTarget: SnapTarget | null;
|
|
38
|
+
edgeLock: {
|
|
39
|
+
edge: {
|
|
40
|
+
v0: Vec3;
|
|
41
|
+
v1: Vec3;
|
|
42
|
+
} | null;
|
|
43
|
+
meshExpressId: number | null;
|
|
44
|
+
edgeT: number;
|
|
45
|
+
shouldLock: boolean;
|
|
46
|
+
shouldRelease: boolean;
|
|
47
|
+
isCorner: boolean;
|
|
48
|
+
cornerValence: number;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export declare class SnapDetector {
|
|
52
|
+
private raycaster;
|
|
53
|
+
private defaultOptions;
|
|
54
|
+
private geometryCache;
|
|
55
|
+
/**
|
|
56
|
+
* Detect best snap target near cursor
|
|
57
|
+
*/
|
|
58
|
+
detectSnapTarget(ray: Ray, meshes: MeshData[], intersection: Intersection | null, camera: {
|
|
59
|
+
position: Vec3;
|
|
60
|
+
fov: number;
|
|
61
|
+
}, screenHeight: number, options?: Partial<SnapOptions>): SnapTarget | null;
|
|
62
|
+
/**
|
|
63
|
+
* Detect snap target with magnetic edge locking behavior
|
|
64
|
+
* This provides the "stick and slide along edges" experience
|
|
65
|
+
*/
|
|
66
|
+
detectMagneticSnap(ray: Ray, meshes: MeshData[], intersection: Intersection | null, camera: {
|
|
67
|
+
position: Vec3;
|
|
68
|
+
fov: number;
|
|
69
|
+
}, screenHeight: number, currentEdgeLock: EdgeLockInput, options?: Partial<SnapOptions>): MagneticSnapResult;
|
|
70
|
+
/**
|
|
71
|
+
* Maintain an existing edge lock - slide along edge or release if moved away
|
|
72
|
+
*/
|
|
73
|
+
private maintainEdgeLock;
|
|
74
|
+
/**
|
|
75
|
+
* Detect if position is at a corner (vertex with multiple edges)
|
|
76
|
+
*/
|
|
77
|
+
private detectCorner;
|
|
78
|
+
/**
|
|
79
|
+
* Get closest point on edge segment with parameter t (0-1)
|
|
80
|
+
*/
|
|
81
|
+
private closestPointOnEdgeWithT;
|
|
82
|
+
/**
|
|
83
|
+
* Check if two vectors are approximately equal
|
|
84
|
+
*/
|
|
85
|
+
private vecEquals;
|
|
86
|
+
/**
|
|
87
|
+
* Get or compute geometry cache for a mesh
|
|
88
|
+
*/
|
|
89
|
+
private getGeometryCache;
|
|
90
|
+
/**
|
|
91
|
+
* Find vertices near point
|
|
92
|
+
*/
|
|
93
|
+
private findVertices;
|
|
94
|
+
/**
|
|
95
|
+
* Find edges near point
|
|
96
|
+
*/
|
|
97
|
+
private findEdges;
|
|
98
|
+
/**
|
|
99
|
+
* Clear geometry cache (call when meshes change)
|
|
100
|
+
*/
|
|
101
|
+
clearCache(): void;
|
|
102
|
+
/**
|
|
103
|
+
* Find faces/planes near intersection
|
|
104
|
+
*/
|
|
105
|
+
private findFaces;
|
|
106
|
+
/**
|
|
107
|
+
* Select best snap target based on confidence and priority
|
|
108
|
+
*/
|
|
109
|
+
private getBestSnapTarget;
|
|
110
|
+
/**
|
|
111
|
+
* Convert screen-space radius to world-space radius
|
|
112
|
+
*/
|
|
113
|
+
private screenToWorldRadius;
|
|
114
|
+
/**
|
|
115
|
+
* Vector utilities
|
|
116
|
+
*/
|
|
117
|
+
private distance;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=snap-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snap-detector.d.ts","sourceRoot":"","sources":["../src/snap-detector.ts"],"names":[],"mappings":"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"}
|