Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XEOK-87 Fix handling of big las models #1658

Merged
merged 12 commits into from
Sep 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 110 additions & 140 deletions dist/xeokit-sdk.cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -67640,27 +67640,6 @@ function getRenderers$3(scene) {
return renderers;
}

/**
* @private
*/
class VBOBatchingPointsBuffer {

constructor(maxGeometryBatchSize = 5000000) {

if (maxGeometryBatchSize > 5000000) {
maxGeometryBatchSize = 5000000;
}

this.maxVerts = maxGeometryBatchSize;
this.maxIndices = maxGeometryBatchSize * 3; // Rough rule-of-thumb
this.positions = [];
this.colors = [];
this.intensities = [];
this.pickColors = [];
this.offsets = [];
}
}

/**
* @private
*/
Expand Down Expand Up @@ -67699,7 +67678,58 @@ class VBOBatchingPointsLayer {

this._renderers = getRenderers$3(cfg.model.scene);

this._buffer = new VBOBatchingPointsBuffer(cfg.maxGeometryBatchSize);
const maxGeometryBatchSize = Math.min(5000000, cfg.maxGeometryBatchSize || window.Infinity);

const attribute = function() {
const portions = [ ];

return {
append: function(data, times = 1, denormalizeScale = 1.0) {
portions.push({ data: data, times: times, denormalizeScale: denormalizeScale });
},
compileBuffer: function(type) {
let len = 0;
portions.forEach(p => { len += p.times * p.data.length; });
const buf = new type(len);

let begin = 0;
portions.forEach(p => {
const data = p.data;
const dScale = p.denormalizeScale;
const subBuf = buf.subarray(begin);

if (dScale === 1.0) {
subBuf.set(data, 0);
} else {
for (let i = 0; i < data.length; ++i) {
subBuf[i] = data[i] * dScale;
}
}

let soFar = data.length;
const allDataLen = p.times * data.length;
while (soFar < allDataLen) {
const toCopy = Math.min(soFar, allDataLen - soFar);
subBuf.set(subBuf.subarray(0, toCopy), soFar);
soFar += toCopy;
}

begin += soFar;
});

return buf;
}
};
};

this._buffer = {
maxVerts: maxGeometryBatchSize,
positions: attribute(),
colors: attribute(),
pickColors: attribute(),
vertsIndex: 0
};

this._scratchMemory = cfg.scratchMemory;

this._state = new RenderState({
Expand Down Expand Up @@ -67764,7 +67794,7 @@ class VBOBatchingPointsLayer {
if (this._finalized) {
throw "Already finalized";
}
return ((this._buffer.positions.length + lenPositions) < (this._buffer.maxVerts * 3));
return (this._buffer.vertsIndex + (lenPositions / 3)) < this._buffer.maxVerts;
}

/**
Expand All @@ -67789,97 +67819,40 @@ class VBOBatchingPointsLayer {
throw "Already finalized";
}

const positions = cfg.positions;
const positionsCompressed = cfg.positionsCompressed;
const color = cfg.color;
const colorsCompressed = cfg.colorsCompressed;
const colors = cfg.colors;
const pickColor = cfg.pickColor;

const buffer = this._buffer;
const positionsIndex = buffer.positions.length;
const vertsIndex = positionsIndex / 3;

let numVerts;

math.expandAABB3(this._modelAABB, cfg.aabb);

if (this._preCompressedPositionsExpected) {

if (!positionsCompressed) {
throw "positionsCompressed expected";
}

for (let i = 0, len = positionsCompressed.length; i < len; i++) {
buffer.positions.push(positionsCompressed[i]);
}

numVerts = positionsCompressed.length / 3;

} else {

if (!positions) {
throw "positions expected";
}
const positions = this._preCompressedPositionsExpected ? cfg.positionsCompressed : cfg.positions;
if (! positions) {
throw ((this._preCompressedPositionsExpected ? "positionsCompressed" : "positions") + " expected");
}

numVerts = positions.length / 3;
buffer.positions.append(positions);

positions.length;
buffer.positions.length;
const numVerts = positions.length / 3;

for (let i = 0, len = positions.length; i < len; i++) {
buffer.positions.push(positions[i]);
}
}
const color = cfg.color;
const colorsCompressed = cfg.colorsCompressed;
const colors = cfg.colors;
const pickColor = cfg.pickColor;

if (colorsCompressed) {
for (let i = 0, len = colorsCompressed.length; i < len; i++) {
buffer.colors.push(colorsCompressed[i]);
}

buffer.colors.append(colorsCompressed);
} else if (colors) {
for (let i = 0, len = colors.length; i < len; i++) {
buffer.colors.push(colors[i] * 255);
}

buffer.colors.append(colors, 1, 255.0);
} else if (color) {

const r = color[0]; // Color is pre-quantized by VBOSceneModel
const g = color[1];
const b = color[2];
const a = 1.0;

for (let i = 0; i < numVerts; i++) {
buffer.colors.push(r);
buffer.colors.push(g);
buffer.colors.push(b);
buffer.colors.push(a);
}
// Color is pre-quantized by VBOSceneModel
buffer.colors.append([ color[0], color[1], color[2], 1.0 ], numVerts);
}

{
const pickColorsBase = buffer.pickColors.length;
const lenPickColors = numVerts * 4;
for (let i = pickColorsBase, len = pickColorsBase + lenPickColors; i < len; i += 4) {
buffer.pickColors.push(pickColor[0]);
buffer.pickColors.push(pickColor[1]);
buffer.pickColors.push(pickColor[2]);
buffer.pickColors.push(pickColor[3]);
}
}
buffer.pickColors.append(pickColor.slice(0, 4), numVerts);

if (this.model.scene.entityOffsetsEnabled) {
for (let i = 0; i < numVerts; i++) {
buffer.offsets.push(0);
buffer.offsets.push(0);
buffer.offsets.push(0);
}
}
math.expandAABB3(this._modelAABB, cfg.aabb);

const portionId = this._portions.length / 2;

this._portions.push(vertsIndex);
this._portions.push(this._buffer.vertsIndex);
this._portions.push(numVerts);
this._buffer.vertsIndex += numVerts;

this._numPortions++;
this.model.numPortions++;
Expand All @@ -67900,43 +67873,20 @@ class VBOBatchingPointsLayer {
const state = this._state;
const gl = this.model.scene.canvas.gl;
const buffer = this._buffer;
const maybeCreateGlBuffer = (srcData, size, usage) => (srcData.length > 0) ? new ArrayBuf(gl, gl.ARRAY_BUFFER, srcData, srcData.length, size, usage) : null;

if (buffer.positions.length > 0) {
if (this._preCompressedPositionsExpected) {
const positions = new Uint16Array(buffer.positions);
state.positionsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, positions, buffer.positions.length, 3, gl.STATIC_DRAW);
} else {
const positions = new Float32Array(buffer.positions);
const quantizedPositions = quantizePositions(positions, this._modelAABB, state.positionsDecodeMatrix);
state.positionsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, quantizedPositions, buffer.positions.length, 3, gl.STATIC_DRAW);
}
}
const positions = (this._preCompressedPositionsExpected
? buffer.positions.compileBuffer(Uint16Array)
: (quantizePositions(buffer.positions.compileBuffer(Float32Array), this._modelAABB, state.positionsDecodeMatrix)));
state.positionsBuf = maybeCreateGlBuffer(positions, 3, gl.STATIC_DRAW);

if (buffer.colors.length > 0) {
const colors = new Uint8Array(buffer.colors);
let normalized = false;
state.colorsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, colors, buffer.colors.length, 4, gl.STATIC_DRAW, normalized);
}
state.flagsBuf = maybeCreateGlBuffer(new Float32Array(this._buffer.vertsIndex), 1, gl.DYNAMIC_DRAW); // Because we build flags arrays here, get their length from the positions array

if (buffer.positions.length > 0) { // Because we build flags arrays here, get their length from the positions array
const flagsLength = buffer.positions.length / 3;
const flags = new Float32Array(flagsLength);
let notNormalized = false;
state.flagsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, flags, flags.length, 1, gl.DYNAMIC_DRAW, notNormalized);
}
state.colorsBuf = maybeCreateGlBuffer(buffer.colors.compileBuffer(Uint8Array), 4, gl.STATIC_DRAW);

if (buffer.pickColors.length > 0) {
const pickColors = new Uint8Array(buffer.pickColors);
let normalized = false;
state.pickColorsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, pickColors, buffer.pickColors.length, 4, gl.STATIC_DRAW, normalized);
}
state.pickColorsBuf = maybeCreateGlBuffer(buffer.pickColors.compileBuffer(Uint8Array), 4, gl.STATIC_DRAW);

if (this.model.scene.entityOffsetsEnabled) {
if (buffer.offsets.length > 0) {
const offsets = new Float32Array(buffer.offsets);
state.offsetsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, offsets, buffer.offsets.length, 3, gl.DYNAMIC_DRAW);
}
}
state.offsetsBuf = this.model.scene.entityOffsetsEnabled ? maybeCreateGlBuffer(new Float32Array(this._buffer.vertsIndex * 3), 3, gl.DYNAMIC_DRAW) : null;

this._buffer = null;
this._finalized = true;
Expand Down Expand Up @@ -88174,6 +88124,7 @@ class DistanceMeasurement extends Component {
this._visible = false;
this._originVisible = false;
this._targetVisible = false;
this._useRotationAdjustment = false;
this._wireVisible = false;
this._axisVisible = false;
this._xAxisVisible = false;
Expand Down Expand Up @@ -88250,7 +88201,7 @@ class DistanceMeasurement extends Component {
this.lengthLabelEnabled = cfg.lengthLabelEnabled;
this.labelsVisible = cfg.labelsVisible;
this.labelsOnWires = cfg.labelsOnWires;
this.useRotationAdjustment = cfg.useRotationAdjustment;
this._useRotationAdjustment = cfg.useRotationAdjustment;

/**
* @type {number[]}
Expand Down Expand Up @@ -88312,7 +88263,7 @@ class DistanceMeasurement extends Component {
this._factors = math.transformVec3(this._axesBasis, delta);

this._measurementOrientation = determineMeasurementOrientation(this._originWorld, this._targetWorld, 0);
if(this._measurementOrientation === 'Vertical' && this.useRotationAdjustment){
if (this._measurementOrientation === 'Vertical' && this._useRotationAdjustment) {
this._wp[0] = this._originWorld[0];
this._wp[1] = this._originWorld[1];
this._wp[2] = this._originWorld[2];
Expand Down Expand Up @@ -88522,7 +88473,7 @@ class DistanceMeasurement extends Component {
}

if (!this._zAxisLabelCulled) {
if(this._measurementOrientation === 'Vertical' && this.useRotationAdjustment) {
if (this._measurementOrientation === 'Vertical' && this._useRotationAdjustment) {
this._zAxisLabel.setPrefix("");
this._zAxisLabel.setText(tilde + Math.abs(math.lenVec3(math.subVec3(this._targetWorld, [this._originWorld[0], this._targetWorld[1], this._originWorld[2]], distVec3)) * scale).toFixed(2) + unitAbbrev);
}
Expand Down Expand Up @@ -88717,6 +88668,25 @@ class DistanceMeasurement extends Component {
return this._targetVisible;
}

/**
* Sets if the measurement is adjusted based on rotation
*
* @type {Boolean}
*/
set useRotationAdjustment(value) {
value = value !== undefined ? Boolean(value) : this.plugin.useRotationAdjustment;
this._useRotationAdjustment = value;
}

/**
* Gets if the measurement is adjusted based on rotation
*
* @type {Boolean}
*/
get useRotationAdjustment() {
return this._useRotationAdjustment;
}

/**
* Sets if the axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target} are enabled.
*
Expand Down Expand Up @@ -91486,12 +91456,6 @@ class FastNavPlugin extends Plugin {
class GLTFDefaultDataSource {

constructor(cfg = {}) {

/**
* Set `true` to enable cache busting for HTTP GETs.
* This is `true` by default.
* @type {boolean}
*/
this.cacheBuster = (cfg.cacheBuster !== false);
}

Expand Down Expand Up @@ -123757,7 +123721,13 @@ class StoreyViewsPlugin extends Plugin {
return null;
}

isPositionAboveOrBelowBuilding(worldPos){
/**
* Returns whether a position is above or below a building
*
* @param {Number[]} worldPos 3D World-space position.
* @returns {String} ID of the lowest/highest story or null.
*/
isPositionAboveOrBelowBuilding(worldPos) {
const keys = Object.keys(this.storeys);
const ids = [keys[0], keys[keys.length-1]];
if(worldPos[1] < this.storeys[ids[0]].storeyAABB[1])
Expand Down
Loading
Loading