@rings-webgpu/core 1.0.29 → 1.0.31

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.
@@ -42153,7 +42153,7 @@ else if (typeof exports === 'object')
42153
42153
  }
42154
42154
  }
42155
42155
 
42156
- const version = "1.0.28";
42156
+ const version = "1.0.30";
42157
42157
 
42158
42158
  class Engine3D {
42159
42159
  /**
@@ -61154,6 +61154,711 @@ fn frag(){
61154
61154
  class KHR_materials_ior {
61155
61155
  }
61156
61156
 
61157
+ class LASUtils {
61158
+ /**
61159
+ * Split array into chunks of specified size
61160
+ */
61161
+ static chunk(arr, size) {
61162
+ const overall = [];
61163
+ let index = 0;
61164
+ while (index < arr.length) {
61165
+ overall.push(arr.slice(index, index + size));
61166
+ index += size;
61167
+ }
61168
+ return overall;
61169
+ }
61170
+ /**
61171
+ * Remove comments from text (lines starting with #)
61172
+ */
61173
+ static removeComment(str) {
61174
+ return str.split("\n").filter((f) => !(f.trim().charAt(0) === "#")).join("\n");
61175
+ }
61176
+ /**
61177
+ * Convert string to number or string
61178
+ * Returns number if string represents a valid number, otherwise returns string
61179
+ */
61180
+ static convertToValue(s) {
61181
+ return Boolean(+s) || /^0|0$/.test(s) ? +s : s;
61182
+ }
61183
+ /**
61184
+ * Parse a LAS section from text
61185
+ * @param text Full LAS file text
61186
+ * @param sectionName Section name (e.g., 'VERSION', 'WELL', 'CURVE')
61187
+ * @returns Section content as string
61188
+ */
61189
+ static parseSection(text, sectionName) {
61190
+ const regex = new RegExp(`~${sectionName}(?:\\w*\\s*)*\\n\\s*`, "i");
61191
+ const parts = text.split(regex);
61192
+ if (parts.length > 1) {
61193
+ return parts[1].split(/~/)[0];
61194
+ }
61195
+ return "";
61196
+ }
61197
+ /**
61198
+ * Parse a parameter line from LAS file
61199
+ * Format: MNEM.UNIT VALUE :DESCRIPTION
61200
+ * @param line Parameter line text
61201
+ * @returns Parsed parameter object
61202
+ */
61203
+ static parseParameterLine(line) {
61204
+ const trimmed = line.trim();
61205
+ if (!trimmed) {
61206
+ return { mnemonic: "", unit: "", value: "", description: "" };
61207
+ }
61208
+ const colonIndex = trimmed.indexOf(":");
61209
+ const beforeColon = colonIndex >= 0 ? trimmed.substring(0, colonIndex).trim() : trimmed;
61210
+ const description = colonIndex >= 0 ? trimmed.substring(colonIndex + 1).trim() : "none";
61211
+ const parts = beforeColon.split(/\s{2,}|\s+/);
61212
+ const mnemonicPart = parts[0] || "";
61213
+ const dotIndex = mnemonicPart.indexOf(".");
61214
+ let mnemonic = "";
61215
+ let unit = "none";
61216
+ if (dotIndex >= 0) {
61217
+ mnemonic = mnemonicPart.substring(0, dotIndex).trim();
61218
+ unit = mnemonicPart.substring(dotIndex + 1).trim() || "none";
61219
+ } else {
61220
+ mnemonic = mnemonicPart.trim();
61221
+ }
61222
+ const value = parts.length > 1 ? parts[parts.length - 1].trim() : "";
61223
+ return {
61224
+ mnemonic: mnemonic.toUpperCase(),
61225
+ unit,
61226
+ value,
61227
+ description: description || "none"
61228
+ };
61229
+ }
61230
+ }
61231
+
61232
+ class LASLoader {
61233
+ /**
61234
+ * Parse LAS file (supports both ASCII text and binary buffer)
61235
+ * @param input LAS file content as string or ArrayBuffer
61236
+ * @returns Parsed LAS data (ASCII or Binary)
61237
+ */
61238
+ async parse(input) {
61239
+ if (input instanceof ArrayBuffer) {
61240
+ const dataView = new DataView(input);
61241
+ const magic = readMagicBytes(dataView);
61242
+ if (magic === "LASF") {
61243
+ return await this.parseBinary(input);
61244
+ } else {
61245
+ const decoder = new TextDecoder("utf-8", { fatal: false });
61246
+ const text = decoder.decode(input);
61247
+ return await this.parseText(text);
61248
+ }
61249
+ } else {
61250
+ return await this.parseText(input);
61251
+ }
61252
+ }
61253
+ /**
61254
+ * Parse ASCII LAS (Log ASCII Standard) format
61255
+ * @param text LAS file content as string
61256
+ * @returns Parsed ASCII LAS data
61257
+ */
61258
+ async parseText(text) {
61259
+ const metadata = this.parseMetadata(text);
61260
+ const wellParams = this.parseWellParams(text);
61261
+ const curveParams = this.parseCurveParams(text);
61262
+ const headers = this.parseHeaders(text);
61263
+ const nullValue = wellParams.NULL?.value;
61264
+ const nullValueNum = typeof nullValue === "string" ? +nullValue : nullValue;
61265
+ const data = this.parseData(text, headers, nullValueNum || -999.25);
61266
+ return {
61267
+ headers,
61268
+ data,
61269
+ wellParams,
61270
+ curveParams,
61271
+ metadata,
61272
+ nullValue: nullValueNum || -999.25
61273
+ };
61274
+ }
61275
+ /**
61276
+ * Parse binary LAS (LIDAR Point Cloud) format
61277
+ * @param buffer LAS file content as ArrayBuffer
61278
+ * @returns Parsed binary LAS data
61279
+ */
61280
+ async parseBinary(buffer) {
61281
+ const dataView = new DataView(buffer);
61282
+ const magic = readMagicBytes(dataView);
61283
+ if (magic !== "LASF") {
61284
+ throw new Error(`LASLoader: Invalid binary LAS file, expected 'LASF' magic bytes, got '${magic}'`);
61285
+ }
61286
+ const versionMinor = dataView.getUint8(24);
61287
+ const versionMajor = dataView.getUint8(25);
61288
+ const version = versionMajor + versionMinor / 10;
61289
+ const pointDataFormat = dataView.getUint8(104);
61290
+ const numPoints = dataView.getUint32(107, true);
61291
+ const xScale = dataView.getFloat64(131, true);
61292
+ const yScale = dataView.getFloat64(139, true);
61293
+ const zScale = dataView.getFloat64(147, true);
61294
+ const xOffset = dataView.getFloat64(155, true);
61295
+ const yOffset = dataView.getFloat64(163, true);
61296
+ const zOffset = dataView.getFloat64(171, true);
61297
+ const xMin = dataView.getFloat64(187, true);
61298
+ const xMax = dataView.getFloat64(195, true);
61299
+ const yMin = dataView.getFloat64(203, true);
61300
+ const yMax = dataView.getFloat64(211, true);
61301
+ const zMin = dataView.getFloat64(219, true);
61302
+ const zMax = dataView.getFloat64(227, true);
61303
+ const offsetToPointData = dataView.getUint32(96, true);
61304
+ const numVLRs = dataView.getUint32(100, true);
61305
+ let pointDataOffset = offsetToPointData;
61306
+ for (let i = 0; i < numVLRs; i++) {
61307
+ const vlrDataLength = dataView.getUint16(pointDataOffset + 54, true);
61308
+ pointDataOffset += 54 + vlrDataLength;
61309
+ }
61310
+ const pointRecordLengths = [20, 28, 26, 34, 57, 63, 30, 36, 38, 59, 67];
61311
+ const pointRecordLength = pointRecordLengths[pointDataFormat] || 20;
61312
+ if (pointDataFormat > 10) {
61313
+ throw new Error(`LASLoader: Unsupported point data format ${pointDataFormat}`);
61314
+ }
61315
+ const positions = new Float32Array(numPoints * 3);
61316
+ const colors = new Uint8Array(numPoints * 4);
61317
+ let baseOffset = pointDataOffset;
61318
+ for (let i = 0; i < numPoints; i++) {
61319
+ const offset = baseOffset + i * pointRecordLength;
61320
+ let xInt, yInt, zInt;
61321
+ if (pointDataFormat >= 6) {
61322
+ xInt = Number(dataView.getBigInt64(offset, true));
61323
+ yInt = Number(dataView.getBigInt64(offset + 8, true));
61324
+ zInt = Number(dataView.getBigInt64(offset + 16, true));
61325
+ } else {
61326
+ xInt = dataView.getInt32(offset, true);
61327
+ yInt = dataView.getInt32(offset + 4, true);
61328
+ zInt = dataView.getInt32(offset + 8, true);
61329
+ }
61330
+ const x = xInt * xScale + xOffset;
61331
+ const y = yInt * yScale + yOffset;
61332
+ const z = zInt * zScale + zOffset;
61333
+ positions[i * 3 + 0] = x;
61334
+ positions[i * 3 + 1] = y;
61335
+ positions[i * 3 + 2] = z;
61336
+ let intensityOffset;
61337
+ if (pointDataFormat >= 6) {
61338
+ intensityOffset = offset + 24;
61339
+ } else {
61340
+ intensityOffset = offset + 12;
61341
+ }
61342
+ const intensity = dataView.getUint16(intensityOffset, true);
61343
+ if ([2, 3, 5, 7, 8, 9, 10].includes(pointDataFormat)) {
61344
+ let rgbOffset;
61345
+ const recordEnd = offset + pointRecordLength;
61346
+ if (pointDataFormat === 5) {
61347
+ rgbOffset = offset + 28;
61348
+ } else if (pointDataFormat === 10) {
61349
+ rgbOffset = offset + 59;
61350
+ } else {
61351
+ rgbOffset = recordEnd - 6;
61352
+ }
61353
+ if (rgbOffset >= offset && rgbOffset + 6 <= recordEnd && rgbOffset + 6 <= buffer.byteLength) {
61354
+ try {
61355
+ const r = dataView.getUint16(rgbOffset, true);
61356
+ const g = dataView.getUint16(rgbOffset + 2, true);
61357
+ const b = dataView.getUint16(rgbOffset + 4, true);
61358
+ colors[i * 4 + 0] = r < 256 ? r : r >> 8;
61359
+ colors[i * 4 + 1] = g < 256 ? g : g >> 8;
61360
+ colors[i * 4 + 2] = b < 256 ? b : b >> 8;
61361
+ colors[i * 4 + 3] = 255;
61362
+ } catch (e) {
61363
+ console.warn(`LASLoader: Failed to read RGB at offset ${rgbOffset} (format ${pointDataFormat}, record length ${pointRecordLength}), using intensity instead. Error: ${e}`);
61364
+ const intensityNorm = Math.min(intensity / 65535, 1);
61365
+ colors[i * 4 + 0] = Math.floor(intensityNorm * 255);
61366
+ colors[i * 4 + 1] = Math.floor(intensityNorm * 255);
61367
+ colors[i * 4 + 2] = Math.floor(intensityNorm * 255);
61368
+ colors[i * 4 + 3] = 255;
61369
+ }
61370
+ } else {
61371
+ console.warn(`LASLoader: RGB offset ${rgbOffset} out of bounds (offset: ${offset}, record end: ${recordEnd}, buffer size: ${buffer.byteLength}, format: ${pointDataFormat}), using intensity instead`);
61372
+ const intensityNorm = Math.min(intensity / 65535, 1);
61373
+ colors[i * 4 + 0] = Math.floor(intensityNorm * 255);
61374
+ colors[i * 4 + 1] = Math.floor(intensityNorm * 255);
61375
+ colors[i * 4 + 2] = Math.floor(intensityNorm * 255);
61376
+ colors[i * 4 + 3] = 255;
61377
+ }
61378
+ } else {
61379
+ const intensityNorm = Math.min(intensity / 65535, 1);
61380
+ colors[i * 4 + 0] = Math.floor(intensityNorm * 255);
61381
+ colors[i * 4 + 1] = Math.floor(intensityNorm * 255);
61382
+ colors[i * 4 + 2] = Math.floor(intensityNorm * 255);
61383
+ colors[i * 4 + 3] = 255;
61384
+ }
61385
+ }
61386
+ return {
61387
+ format: "binary",
61388
+ version,
61389
+ pointDataFormat,
61390
+ numPoints,
61391
+ positions,
61392
+ colors,
61393
+ bbox: { xMin, xMax, yMin, yMax, zMin, zMax },
61394
+ scale: { x: xScale, y: yScale, z: zScale },
61395
+ offset: { x: xOffset, y: yOffset, z: zOffset }
61396
+ };
61397
+ }
61398
+ /**
61399
+ * Parse version information section (~VERSION)
61400
+ */
61401
+ parseMetadata(text) {
61402
+ const versionSection = LASUtils.parseSection(text, "V");
61403
+ if (!versionSection) {
61404
+ throw new Error("LASLoader: ~VERSION section not found");
61405
+ }
61406
+ const cleaned = LASUtils.removeComment(versionSection);
61407
+ const lines = cleaned.split("\n").filter(Boolean);
61408
+ let version = 2;
61409
+ let wrap = false;
61410
+ for (const line of lines) {
61411
+ const parts = line.split(/\s{2,}|\s*:/).filter(Boolean);
61412
+ if (parts.length >= 2) {
61413
+ const key = parts[0].trim().toUpperCase();
61414
+ const value = parts[1].trim().toUpperCase();
61415
+ if (key === "VERS" || key === "VERSION") {
61416
+ const versionMatch = value.match(/(\d+\.?\d*)/);
61417
+ if (versionMatch) {
61418
+ version = +versionMatch[1];
61419
+ }
61420
+ } else if (key === "WRAP" || key === "WRAP.") {
61421
+ wrap = value === "YES" || value === "Y";
61422
+ }
61423
+ }
61424
+ }
61425
+ return { version, wrap };
61426
+ }
61427
+ /**
61428
+ * Parse well information section (~WELL)
61429
+ */
61430
+ parseWellParams(text) {
61431
+ const wellSection = LASUtils.parseSection(text, "W");
61432
+ if (!wellSection) {
61433
+ return {};
61434
+ }
61435
+ const cleaned = LASUtils.removeComment(wellSection);
61436
+ const lines = cleaned.split("\n").filter(Boolean);
61437
+ const params = {};
61438
+ for (const line of lines) {
61439
+ const parsed = LASUtils.parseParameterLine(line);
61440
+ if (parsed.mnemonic) {
61441
+ params[parsed.mnemonic] = {
61442
+ unit: parsed.unit,
61443
+ value: LASUtils.convertToValue(parsed.value),
61444
+ description: parsed.description
61445
+ };
61446
+ }
61447
+ }
61448
+ return params;
61449
+ }
61450
+ /**
61451
+ * Parse curve information section (~CURVE)
61452
+ */
61453
+ parseCurveParams(text) {
61454
+ const curveSection = LASUtils.parseSection(text, "C");
61455
+ if (!curveSection) {
61456
+ return {};
61457
+ }
61458
+ const cleaned = LASUtils.removeComment(curveSection);
61459
+ const lines = cleaned.split("\n").filter(Boolean);
61460
+ const params = {};
61461
+ for (const line of lines) {
61462
+ const parsed = LASUtils.parseParameterLine(line);
61463
+ if (parsed.mnemonic) {
61464
+ params[parsed.mnemonic] = {
61465
+ unit: parsed.unit,
61466
+ value: parsed.value,
61467
+ description: parsed.description
61468
+ };
61469
+ }
61470
+ }
61471
+ return params;
61472
+ }
61473
+ /**
61474
+ * Parse headers (column names) from curve section
61475
+ */
61476
+ parseHeaders(text) {
61477
+ const curveSection = LASUtils.parseSection(text, "C");
61478
+ if (!curveSection) {
61479
+ throw new Error("LASLoader: ~CURVE section not found");
61480
+ }
61481
+ const cleaned = LASUtils.removeComment(curveSection);
61482
+ const lines = cleaned.split("\n").filter(Boolean);
61483
+ const headers = [];
61484
+ for (const line of lines) {
61485
+ const parsed = LASUtils.parseParameterLine(line);
61486
+ if (parsed.mnemonic) {
61487
+ headers.push(parsed.mnemonic);
61488
+ }
61489
+ }
61490
+ if (headers.length === 0) {
61491
+ throw new Error("LASLoader: No headers found in ~CURVE section");
61492
+ }
61493
+ return headers;
61494
+ }
61495
+ /**
61496
+ * Parse ASCII data section (~A)
61497
+ */
61498
+ parseData(text, headers, nullValue) {
61499
+ const dataMatch = text.match(/~A(?:[\x20-\x7E])*(?:\r\n|\r|\n)([\s\S]*?)(?=~|$)/);
61500
+ if (!dataMatch || !dataMatch[1]) {
61501
+ throw new Error("LASLoader: ~A data section not found");
61502
+ }
61503
+ const dataSection = dataMatch[1].trim();
61504
+ if (!dataSection) {
61505
+ throw new Error("LASLoader: Data section is empty");
61506
+ }
61507
+ const values = dataSection.split(/\s+/).filter((v) => v.trim().length > 0).map((m) => LASUtils.convertToValue(m.trim()));
61508
+ if (values.length === 0) {
61509
+ throw new Error("LASLoader: No data values found");
61510
+ }
61511
+ const rowCount = Math.floor(values.length / headers.length);
61512
+ if (rowCount === 0) {
61513
+ throw new Error("LASLoader: Insufficient data values");
61514
+ }
61515
+ const data = [];
61516
+ for (let i = 0; i < rowCount; i++) {
61517
+ const row = [];
61518
+ for (let j = 0; j < headers.length; j++) {
61519
+ const idx = i * headers.length + j;
61520
+ if (idx < values.length) {
61521
+ row.push(values[idx]);
61522
+ }
61523
+ }
61524
+ if (row.length === headers.length) {
61525
+ data.push(row);
61526
+ }
61527
+ }
61528
+ return data;
61529
+ }
61530
+ }
61531
+
61532
+ var LASVisualizationMode = /* @__PURE__ */ ((LASVisualizationMode2) => {
61533
+ LASVisualizationMode2["PointCloud"] = "pointcloud";
61534
+ LASVisualizationMode2["Curve"] = "curve";
61535
+ LASVisualizationMode2["WellTrajectory"] = "trajectory";
61536
+ return LASVisualizationMode2;
61537
+ })(LASVisualizationMode || {});
61538
+
61539
+ var __getOwnPropDesc$4 = Object.getOwnPropertyDescriptor;
61540
+ var __decorateClass$4 = (decorators, target, key, kind) => {
61541
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$4(target, key) : target;
61542
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
61543
+ if (decorator = decorators[i])
61544
+ result = (decorator(result)) || result;
61545
+ return result;
61546
+ };
61547
+ exports.FatLineShader = class FatLineShader extends Shader {
61548
+ constructor() {
61549
+ super();
61550
+ const colorShader = new RenderShaderPass("FatLine_VS", "FatLine_FS");
61551
+ colorShader.setShaderEntry(`VertMain`, `FragMain`);
61552
+ this.addRenderPass(colorShader);
61553
+ const shaderState = colorShader.shaderState;
61554
+ shaderState.acceptShadow = false;
61555
+ shaderState.castShadow = false;
61556
+ shaderState.receiveEnv = false;
61557
+ shaderState.acceptGI = false;
61558
+ shaderState.useLight = false;
61559
+ shaderState.cullMode = GPUCullMode.none;
61560
+ shaderState.depthWriteEnabled = true;
61561
+ this.setDefault();
61562
+ }
61563
+ /**
61564
+ * Set default uniform values
61565
+ */
61566
+ setDefault() {
61567
+ this.setUniformColor(`baseColor`, new Color(1, 1, 1, 1));
61568
+ this.setUniformFloat(`lineWidth`, 1);
61569
+ this.setUniformFloat(`opacity`, 1);
61570
+ this.setUniformVector2(`resolution`, new Vector2(1920, 1080));
61571
+ const identityMatrix = new Matrix4();
61572
+ const pass = this.getDefaultColorShader();
61573
+ pass.setUniform(`modelMatrix`, identityMatrix.rawData);
61574
+ }
61575
+ };
61576
+ exports.FatLineShader = __decorateClass$4([
61577
+ RegisterShader(exports.FatLineShader, "FatLineShader")
61578
+ ], exports.FatLineShader);
61579
+
61580
+ class FatLineMaterial extends Material {
61581
+ constructor() {
61582
+ super();
61583
+ this.shader = new exports.FatLineShader();
61584
+ this.transparent = true;
61585
+ }
61586
+ /**
61587
+ * Set instance buffer for line segments
61588
+ * This should be called after setting the geometry
61589
+ */
61590
+ setInstanceBuffer(buffer) {
61591
+ this.shader.setStorageBuffer("instances", buffer);
61592
+ }
61593
+ /**
61594
+ * Set model matrix for transforming line segments
61595
+ * This should be updated each frame if the object moves
61596
+ */
61597
+ setModelMatrix(matrix) {
61598
+ const pass = this.shader.getDefaultColorShader();
61599
+ pass.setUniform("modelMatrix", matrix.rawData);
61600
+ }
61601
+ /**
61602
+ * Set base color (tint color)
61603
+ */
61604
+ set baseColor(color) {
61605
+ this.shader.setUniformColor(`baseColor`, color);
61606
+ }
61607
+ /**
61608
+ * Get base color (tint color)
61609
+ */
61610
+ get baseColor() {
61611
+ return this.shader.getUniformColor("baseColor");
61612
+ }
61613
+ /**
61614
+ * Set line width in pixels
61615
+ */
61616
+ set lineWidth(value) {
61617
+ this.shader.setUniformFloat(`lineWidth`, value);
61618
+ }
61619
+ /**
61620
+ * Get line width in pixels
61621
+ */
61622
+ get lineWidth() {
61623
+ return this.shader.getUniformFloat("lineWidth");
61624
+ }
61625
+ /**
61626
+ * Set opacity (0-1)
61627
+ */
61628
+ set opacity(value) {
61629
+ this.shader.setUniformFloat(`opacity`, value);
61630
+ }
61631
+ /**
61632
+ * Get opacity (0-1)
61633
+ */
61634
+ get opacity() {
61635
+ return this.shader.getUniformFloat("opacity");
61636
+ }
61637
+ /**
61638
+ * Set viewport resolution for correct pixel-space calculations
61639
+ * This should be set automatically by the renderer
61640
+ */
61641
+ set resolution(value) {
61642
+ this.shader.setUniformVector2(`resolution`, value);
61643
+ }
61644
+ /**
61645
+ * Get viewport resolution
61646
+ */
61647
+ get resolution() {
61648
+ return this.shader.getUniformVector2("resolution");
61649
+ }
61650
+ }
61651
+
61652
+ class LASParser extends ParserBase {
61653
+ static format = ParserFormat.BIN;
61654
+ // Can handle both binary and text
61655
+ visualizationMode = LASVisualizationMode.PointCloud;
61656
+ async parseBuffer(buffer) {
61657
+ const loader = new LASLoader();
61658
+ const parsedData = await loader.parse(buffer);
61659
+ await this.createVisualization(parsedData);
61660
+ }
61661
+ /**
61662
+ * Create visualization from parsed LAS data
61663
+ */
61664
+ async createVisualization(parsedData) {
61665
+ if ("format" in parsedData && parsedData.format === "binary") {
61666
+ this.data = this.createBinaryPointCloudVisualization(parsedData);
61667
+ } else {
61668
+ const asciiData = parsedData;
61669
+ let result;
61670
+ switch (this.visualizationMode) {
61671
+ case LASVisualizationMode.PointCloud:
61672
+ result = this.createPointCloudVisualization(asciiData);
61673
+ break;
61674
+ case LASVisualizationMode.Curve:
61675
+ result = this.createCurveVisualization(asciiData);
61676
+ break;
61677
+ case LASVisualizationMode.WellTrajectory:
61678
+ result = this.createWellTrajectoryVisualization(asciiData);
61679
+ break;
61680
+ default:
61681
+ result = this.createPointCloudVisualization(asciiData);
61682
+ }
61683
+ result["lasData"] = asciiData;
61684
+ result["wellParams"] = asciiData.wellParams;
61685
+ result["curveParams"] = asciiData.curveParams;
61686
+ this.data = result;
61687
+ }
61688
+ }
61689
+ /**
61690
+ * Create point cloud visualization from binary LAS data
61691
+ */
61692
+ createBinaryPointCloudVisualization(binaryData) {
61693
+ const pointCloudObj = new exports.Object3D();
61694
+ pointCloudObj.name = "LASPointCloud";
61695
+ const pointCloudObjRoot = new exports.Object3D();
61696
+ pointCloudObjRoot.name = "LASPointCloudRoot";
61697
+ pointCloudObj.addChild(pointCloudObjRoot);
61698
+ const renderer = pointCloudObjRoot.addComponent(exports.PointCloudRenderer);
61699
+ renderer.initFromData(binaryData.positions, binaryData.colors, binaryData.numPoints);
61700
+ renderer.setPointShape("circle");
61701
+ renderer.setPointSize(4);
61702
+ pointCloudObj["lasFormat"] = "binary";
61703
+ pointCloudObj["lasVersion"] = binaryData.version;
61704
+ pointCloudObj["numPoints"] = binaryData.numPoints;
61705
+ pointCloudObj["pointDataFormat"] = binaryData.pointDataFormat;
61706
+ pointCloudObj["bbox"] = binaryData.bbox;
61707
+ return pointCloudObj;
61708
+ }
61709
+ verification() {
61710
+ if (this.data) {
61711
+ return true;
61712
+ }
61713
+ throw new Error("LASParser: Parse failed");
61714
+ }
61715
+ /**
61716
+ * Create point cloud visualization from LAS data
61717
+ * Depth as Z axis, curve values as X/Y axes
61718
+ */
61719
+ createPointCloudVisualization(lasData) {
61720
+ const { headers, data, nullValue } = lasData;
61721
+ const depthIndex = headers.findIndex(
61722
+ (h) => h.toUpperCase() === "DEPTH" || h.toUpperCase() === "DEPT"
61723
+ );
61724
+ if (depthIndex < 0) {
61725
+ throw new Error("LASParser: DEPTH column not found");
61726
+ }
61727
+ const curveIndices = headers.map((_, i) => i).filter((i) => i !== depthIndex).slice(0, 2);
61728
+ const validData = data.filter(
61729
+ (row) => !row.some((val) => val === nullValue || val === +nullValue)
61730
+ );
61731
+ if (validData.length === 0) {
61732
+ throw new Error("LASParser: No valid data points after filtering");
61733
+ }
61734
+ const pointCount = validData.length;
61735
+ const positions = new Float32Array(pointCount * 3);
61736
+ const colors = new Uint8Array(pointCount * 4);
61737
+ let minX = Infinity, maxX = -Infinity;
61738
+ let minY = Infinity, maxY = -Infinity;
61739
+ if (curveIndices.length > 0) {
61740
+ const xValues = validData.map((row) => +row[curveIndices[0]]).filter((v) => !isNaN(v));
61741
+ minX = Math.min(...xValues);
61742
+ maxX = Math.max(...xValues);
61743
+ if (curveIndices.length > 1) {
61744
+ const yValues = validData.map((row) => +row[curveIndices[1]]).filter((v) => !isNaN(v));
61745
+ minY = Math.min(...yValues);
61746
+ maxY = Math.max(...yValues);
61747
+ }
61748
+ }
61749
+ for (let i = 0; i < validData.length; i++) {
61750
+ const row = validData[i];
61751
+ const idx = i * 3;
61752
+ const colorIdx = i * 4;
61753
+ positions[idx + 2] = +row[depthIndex];
61754
+ if (curveIndices.length > 0) {
61755
+ const xValue = +row[curveIndices[0]];
61756
+ const normalizedX = maxX !== minX ? (xValue - minX) / (maxX - minX) : 0;
61757
+ positions[idx + 0] = normalizedX * 10;
61758
+ if (curveIndices.length > 1) {
61759
+ const yValue = +row[curveIndices[1]];
61760
+ const normalizedY = maxY !== minY ? (yValue - minY) / (maxY - minY) : 0;
61761
+ positions[idx + 1] = normalizedY * 10;
61762
+ } else {
61763
+ positions[idx + 1] = 0;
61764
+ }
61765
+ } else {
61766
+ positions[idx + 0] = 0;
61767
+ positions[idx + 1] = 0;
61768
+ }
61769
+ if (curveIndices.length > 0) {
61770
+ const curveValue = +row[curveIndices[0]];
61771
+ const normalizedValue = maxX !== minX ? (curveValue - minX) / (maxX - minX) : 0;
61772
+ this.mapValueToColor(normalizedValue, colors, colorIdx);
61773
+ } else {
61774
+ colors[colorIdx + 0] = 255;
61775
+ colors[colorIdx + 1] = 255;
61776
+ colors[colorIdx + 2] = 255;
61777
+ colors[colorIdx + 3] = 255;
61778
+ }
61779
+ }
61780
+ const pointCloudObj = new exports.Object3D();
61781
+ pointCloudObj.name = "LASPointCloud";
61782
+ const renderer = pointCloudObj.addComponent(exports.PointCloudRenderer);
61783
+ renderer.initFromData(positions, colors, pointCount);
61784
+ renderer.setPointShape("circle");
61785
+ renderer.setPointSize(4);
61786
+ return pointCloudObj;
61787
+ }
61788
+ /**
61789
+ * Create curve visualization using FatLineRenderer
61790
+ * Depth as Z axis, normalized curve value as X axis
61791
+ */
61792
+ createCurveVisualization(lasData) {
61793
+ const { headers, data, nullValue } = lasData;
61794
+ const depthIndex = headers.findIndex(
61795
+ (h) => h.toUpperCase() === "DEPTH" || h.toUpperCase() === "DEPT"
61796
+ );
61797
+ if (depthIndex < 0) {
61798
+ throw new Error("LASParser: DEPTH column not found");
61799
+ }
61800
+ const curveIndex = headers.map((_, i) => i).find((i) => i !== depthIndex);
61801
+ if (curveIndex === void 0) {
61802
+ throw new Error("LASParser: No curve column found");
61803
+ }
61804
+ const validData = data.filter((row) => {
61805
+ const depth = +row[depthIndex];
61806
+ const curveValue = +row[curveIndex];
61807
+ return !isNaN(depth) && !isNaN(curveValue) && curveValue !== nullValue && curveValue !== +nullValue;
61808
+ });
61809
+ if (validData.length === 0) {
61810
+ throw new Error("LASParser: No valid data points");
61811
+ }
61812
+ const curveValues = validData.map((row) => +row[curveIndex]);
61813
+ const minCurve = Math.min(...curveValues);
61814
+ const maxCurve = Math.max(...curveValues);
61815
+ const curveRange = maxCurve - minCurve;
61816
+ const positions = new Float32Array(validData.length * 3);
61817
+ for (let i = 0; i < validData.length; i++) {
61818
+ const row = validData[i];
61819
+ const idx = i * 3;
61820
+ const depth = +row[depthIndex];
61821
+ const curveValue = +row[curveIndex];
61822
+ positions[idx + 2] = depth;
61823
+ const normalizedCurve = curveRange > 0 ? (curveValue - minCurve) / curveRange : 0;
61824
+ positions[idx + 0] = normalizedCurve * 10;
61825
+ positions[idx + 1] = 0;
61826
+ }
61827
+ const geometry = new FatLineGeometry();
61828
+ geometry.setPositions(positions);
61829
+ const material = new FatLineMaterial();
61830
+ material.baseColor = new Color(1, 0, 0, 1);
61831
+ material.lineWidth = 2;
61832
+ const curveObj = new exports.Object3D();
61833
+ curveObj.name = `LASCurve_${headers[curveIndex]}`;
61834
+ const renderer = curveObj.addComponent(exports.FatLineRenderer);
61835
+ renderer.geometry = geometry;
61836
+ renderer.material = material;
61837
+ return curveObj;
61838
+ }
61839
+ /**
61840
+ * Create well trajectory visualization
61841
+ * TODO: Implement when well trajectory data is available
61842
+ */
61843
+ createWellTrajectoryVisualization(lasData) {
61844
+ throw new Error("LASParser: Well trajectory visualization not yet implemented");
61845
+ }
61846
+ normalizeValue(value, data, columnIndex) {
61847
+ const values = data.map((row) => +row[columnIndex]).filter((v) => !isNaN(v));
61848
+ const min = Math.min(...values);
61849
+ const max = Math.max(...values);
61850
+ return max !== min ? (value - min) / (max - min) : 0;
61851
+ }
61852
+ mapValueToColor(normalizedValue, colors, index) {
61853
+ const r = Math.floor(normalizedValue * 255);
61854
+ const b = Math.floor((1 - normalizedValue) * 255);
61855
+ colors[index + 0] = r;
61856
+ colors[index + 1] = 0;
61857
+ colors[index + 2] = b;
61858
+ colors[index + 3] = 255;
61859
+ }
61860
+ }
61861
+
61157
61862
  class PlyParser extends ParserBase {
61158
61863
  static format = ParserFormat.BIN;
61159
61864
  async parseBuffer(buffer) {
@@ -61364,6 +62069,8 @@ fn frag(){
61364
62069
  const pointCloudObj = new exports.Object3D();
61365
62070
  const renderer = pointCloudObj.addComponent(exports.PointCloudRenderer);
61366
62071
  renderer.initFromData(positions, colors, pointsLength);
62072
+ renderer.setPointShape("circle");
62073
+ renderer.setPointSize(4);
61367
62074
  const rtcCenter = featureTable.getData("RTC_CENTER", 1, "FLOAT", "VEC3");
61368
62075
  if (rtcCenter) {
61369
62076
  pointCloudObj.transform.localPosition.set(
@@ -62503,9 +63210,9 @@ fn frag(){
62503
63210
  }
62504
63211
  }
62505
63212
 
62506
- var __getOwnPropDesc$4 = Object.getOwnPropertyDescriptor;
62507
- var __decorateClass$4 = (decorators, target, key, kind) => {
62508
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$4(target, key) : target;
63213
+ var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
63214
+ var __decorateClass$3 = (decorators, target, key, kind) => {
63215
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
62509
63216
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
62510
63217
  if (decorator = decorators[i])
62511
63218
  result = (decorator(result)) || result;
@@ -62624,13 +63331,13 @@ fn frag(){
62624
63331
  }
62625
63332
  }
62626
63333
  };
62627
- exports.LitSSSShader = __decorateClass$4([
63334
+ exports.LitSSSShader = __decorateClass$3([
62628
63335
  RegisterShader(exports.LitSSSShader, "LitSSSShader")
62629
63336
  ], exports.LitSSSShader);
62630
63337
 
62631
- var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
62632
- var __decorateClass$3 = (decorators, target, key, kind) => {
62633
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
63338
+ var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
63339
+ var __decorateClass$2 = (decorators, target, key, kind) => {
63340
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
62634
63341
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
62635
63342
  if (decorator = decorators[i])
62636
63343
  result = (decorator(result)) || result;
@@ -62726,7 +63433,7 @@ fn frag(){
62726
63433
  }
62727
63434
  }
62728
63435
  };
62729
- exports.LitShader = __decorateClass$3([
63436
+ exports.LitShader = __decorateClass$2([
62730
63437
  RegisterShader(exports.LitShader, "LitShader")
62731
63438
  ], exports.LitShader);
62732
63439
 
@@ -62885,47 +63592,6 @@ fn frag(){
62885
63592
  }
62886
63593
  }
62887
63594
 
62888
- var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
62889
- var __decorateClass$2 = (decorators, target, key, kind) => {
62890
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
62891
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
62892
- if (decorator = decorators[i])
62893
- result = (decorator(result)) || result;
62894
- return result;
62895
- };
62896
- exports.FatLineShader = class FatLineShader extends Shader {
62897
- constructor() {
62898
- super();
62899
- const colorShader = new RenderShaderPass("FatLine_VS", "FatLine_FS");
62900
- colorShader.setShaderEntry(`VertMain`, `FragMain`);
62901
- this.addRenderPass(colorShader);
62902
- const shaderState = colorShader.shaderState;
62903
- shaderState.acceptShadow = false;
62904
- shaderState.castShadow = false;
62905
- shaderState.receiveEnv = false;
62906
- shaderState.acceptGI = false;
62907
- shaderState.useLight = false;
62908
- shaderState.cullMode = GPUCullMode.none;
62909
- shaderState.depthWriteEnabled = true;
62910
- this.setDefault();
62911
- }
62912
- /**
62913
- * Set default uniform values
62914
- */
62915
- setDefault() {
62916
- this.setUniformColor(`baseColor`, new Color(1, 1, 1, 1));
62917
- this.setUniformFloat(`lineWidth`, 1);
62918
- this.setUniformFloat(`opacity`, 1);
62919
- this.setUniformVector2(`resolution`, new Vector2(1920, 1080));
62920
- const identityMatrix = new Matrix4();
62921
- const pass = this.getDefaultColorShader();
62922
- pass.setUniform(`modelMatrix`, identityMatrix.rawData);
62923
- }
62924
- };
62925
- exports.FatLineShader = __decorateClass$2([
62926
- RegisterShader(exports.FatLineShader, "FatLineShader")
62927
- ], exports.FatLineShader);
62928
-
62929
63595
  var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
62930
63596
  var __decorateClass$1 = (decorators, target, key, kind) => {
62931
63597
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
@@ -65299,78 +65965,6 @@ fn frag(){
65299
65965
  }
65300
65966
  }
65301
65967
 
65302
- class FatLineMaterial extends Material {
65303
- constructor() {
65304
- super();
65305
- this.shader = new exports.FatLineShader();
65306
- this.transparent = true;
65307
- }
65308
- /**
65309
- * Set instance buffer for line segments
65310
- * This should be called after setting the geometry
65311
- */
65312
- setInstanceBuffer(buffer) {
65313
- this.shader.setStorageBuffer("instances", buffer);
65314
- }
65315
- /**
65316
- * Set model matrix for transforming line segments
65317
- * This should be updated each frame if the object moves
65318
- */
65319
- setModelMatrix(matrix) {
65320
- const pass = this.shader.getDefaultColorShader();
65321
- pass.setUniform("modelMatrix", matrix.rawData);
65322
- }
65323
- /**
65324
- * Set base color (tint color)
65325
- */
65326
- set baseColor(color) {
65327
- this.shader.setUniformColor(`baseColor`, color);
65328
- }
65329
- /**
65330
- * Get base color (tint color)
65331
- */
65332
- get baseColor() {
65333
- return this.shader.getUniformColor("baseColor");
65334
- }
65335
- /**
65336
- * Set line width in pixels
65337
- */
65338
- set lineWidth(value) {
65339
- this.shader.setUniformFloat(`lineWidth`, value);
65340
- }
65341
- /**
65342
- * Get line width in pixels
65343
- */
65344
- get lineWidth() {
65345
- return this.shader.getUniformFloat("lineWidth");
65346
- }
65347
- /**
65348
- * Set opacity (0-1)
65349
- */
65350
- set opacity(value) {
65351
- this.shader.setUniformFloat(`opacity`, value);
65352
- }
65353
- /**
65354
- * Get opacity (0-1)
65355
- */
65356
- get opacity() {
65357
- return this.shader.getUniformFloat("opacity");
65358
- }
65359
- /**
65360
- * Set viewport resolution for correct pixel-space calculations
65361
- * This should be set automatically by the renderer
65362
- */
65363
- set resolution(value) {
65364
- this.shader.setUniformVector2(`resolution`, value);
65365
- }
65366
- /**
65367
- * Get viewport resolution
65368
- */
65369
- get resolution() {
65370
- return this.shader.getUniformVector2("resolution");
65371
- }
65372
- }
65373
-
65374
65968
  class LambertMaterial extends Material {
65375
65969
  /**
65376
65970
  * @constructor
@@ -71390,6 +71984,10 @@ fn frag(){
71390
71984
  exports.KeyEvent = KeyEvent;
71391
71985
  exports.Keyframe = Keyframe;
71392
71986
  exports.KeyframeT = KeyframeT;
71987
+ exports.LASLoader = LASLoader;
71988
+ exports.LASParser = LASParser;
71989
+ exports.LASUtils = LASUtils;
71990
+ exports.LASVisualizationMode = LASVisualizationMode;
71393
71991
  exports.LDRTextureCube = LDRTextureCube;
71394
71992
  exports.LOADED = LOADED;
71395
71993
  exports.LOADING = LOADING;