@xeokit/xeokit-sdk 2.6.95 → 2.6.97
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/dist/xeokit-sdk.cjs.js +1303 -179
- package/dist/xeokit-sdk.es.js +1302 -180
- package/dist/xeokit-sdk.es5.js +762 -438
- package/dist/xeokit-sdk.min.cjs.js +7 -7
- package/dist/xeokit-sdk.min.es.js +7 -7
- package/dist/xeokit-sdk.min.es5.js +6 -6
- package/package.json +1 -1
- package/src/plugins/IFCOpenShellLoaderPlugin/IFCOpenShellDefaultDataSource.js +74 -0
- package/src/plugins/IFCOpenShellLoaderPlugin/IFCOpenShellLoaderPlugin.js +900 -0
- package/src/plugins/IFCOpenShellLoaderPlugin/index.js +2 -0
- package/src/plugins/index.js +1 -0
- package/src/viewer/scene/CameraControl/CameraControl.js +2 -2
- package/src/viewer/scene/math/math.js +171 -106
- package/src/viewer/scene/model/SceneModel.js +26 -23
- package/src/viewer/scene/model/SceneModelMesh.js +2 -0
- package/src/viewer/scene/model/compression.js +6 -6
- package/src/viewer/scene/model/layer/DTXLayer.js +5 -1
- package/src/viewer/scene/model/layer/Layer.js +11 -11
- package/src/viewer/scene/model/layer/VBOLayer.js +7 -3
- package/src/viewer/scene/sectionCaps/SectionCaps.js +5 -4
- package/src/viewer/scene/webgl/Renderer.js +79 -4
- package/types/plugins/IFCOpenShellLoaderPlugin/IFCOpenShellLoaderPlugin.d.ts +107 -0
- package/types/plugins/IFCOpenShellLoaderPlugin/index.d.ts +1 -0
- package/types/plugins/index.d.ts +1 -0
- package/types/viewer/scene/CameraControl/CameraControl.d.ts +5 -5
package/src/plugins/index.js
CHANGED
|
@@ -18,6 +18,7 @@ export * from "./XKTLoaderPlugin/index.js";
|
|
|
18
18
|
export * from "./XML3DLoaderPlugin/index.js";
|
|
19
19
|
export * from "./WebIFCLoaderPlugin/index.js";
|
|
20
20
|
export * from "./CxConverterIFCLoaderPlugin/index.js";
|
|
21
|
+
export * from "./IFCOpenShellLoaderPlugin/index.js";
|
|
21
22
|
export * from "./LASLoaderPlugin/index.js";
|
|
22
23
|
export * from "./CityJSONLoaderPlugin/index.js";
|
|
23
24
|
export * from "./DotBIMLoaderPlugin/index.js";
|
|
@@ -867,7 +867,7 @@ class CameraControl extends Component {
|
|
|
867
867
|
*
|
|
868
868
|
* See class docs for usage.
|
|
869
869
|
*
|
|
870
|
-
* @param {{Number:Number}|String} value Either a set of new key mappings, or a string to select a keyboard layout,
|
|
870
|
+
* @param {{Number:(Number | Number[])[]} | String} value Either a set of new key mappings, or a string to select a keyboard layout,
|
|
871
871
|
* which causes ````CameraControl```` to use the default key mappings for that layout.
|
|
872
872
|
*/
|
|
873
873
|
set keyMap(value) {
|
|
@@ -946,7 +946,7 @@ class CameraControl extends Component {
|
|
|
946
946
|
/**
|
|
947
947
|
* Gets custom mappings of keys to {@link CameraControl} actions.
|
|
948
948
|
*
|
|
949
|
-
* @returns {{Number:Number}} Current key mappings.
|
|
949
|
+
* @returns {{Number:(Number | Number[])[]}} Current key mappings.
|
|
950
950
|
*/
|
|
951
951
|
get keyMap() {
|
|
952
952
|
return this._keyMap;
|
|
@@ -5475,9 +5475,12 @@ math.makeSectionPlaneSlicer = (function() {
|
|
|
5475
5475
|
const tempVec3d = math.vec3();
|
|
5476
5476
|
|
|
5477
5477
|
const triangle = [ math.vec3(), math.vec3(), math.vec3() ];
|
|
5478
|
+
const tmpIntersections = [ null, null, null ];
|
|
5479
|
+
const tmpPositions = [ null, null, null ];
|
|
5480
|
+
const tmpReferences = [ null, null, null ];
|
|
5478
5481
|
|
|
5479
|
-
const worldUp = [0, 1, 0];
|
|
5480
5482
|
const worldRight = [1, 0, 0];
|
|
5483
|
+
const worldUp = [0, 1, 0];
|
|
5481
5484
|
const worldForward = [0, 0, 1];
|
|
5482
5485
|
|
|
5483
5486
|
const sqDistVec3 = (function() {
|
|
@@ -5492,84 +5495,113 @@ math.makeSectionPlaneSlicer = (function() {
|
|
|
5492
5495
|
return ret;
|
|
5493
5496
|
};
|
|
5494
5497
|
|
|
5495
|
-
const setCoord2D = (p, dst) => { dst[0] = p.coord2Dx; dst[1] = p.coord2Dy; return dst; };
|
|
5496
|
-
|
|
5497
5498
|
const ccw = (a, b, c) => ((c[1] - a[1]) * (b[0] - a[0])) > ((b[1] - a[1]) * (c[0] - a[0]));
|
|
5498
5499
|
|
|
5499
|
-
|
|
5500
|
-
const
|
|
5501
|
-
const
|
|
5502
|
-
|
|
5503
|
-
return false;
|
|
5504
|
-
}
|
|
5500
|
+
return function(plane) {
|
|
5501
|
+
const planeU = math.vec3ApplyQuaternion(plane.quaternion, worldRight, math.vec3());
|
|
5502
|
+
const planeV = math.vec3ApplyQuaternion(plane.quaternion, worldUp, math.vec3());
|
|
5503
|
+
const planeN = math.vec3ApplyQuaternion(plane.quaternion, worldForward, math.vec3());
|
|
5505
5504
|
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
const i0 = setCoord2D(innerEndpoints[ii], tempVec2a);
|
|
5510
|
-
const [i0x, i0y] = i0;
|
|
5511
|
-
const i1 = setCoord2D(innerEndpoints[ij], tempVec2b);
|
|
5505
|
+
return function(mesh, cfg = { }) {
|
|
5506
|
+
const planeToMesh = math.subVec3(mesh.origin, plane.pos, math.vec3());
|
|
5507
|
+
const planeDist = math.dotVec3(planeN, planeToMesh);
|
|
5512
5508
|
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
const
|
|
5509
|
+
const unsortedSegment = [ ];
|
|
5510
|
+
const indexedPositions = [ null ]; // to never return 0 from addPosition, so its result can be used as a predicate
|
|
5511
|
+
const addPosition = (p, addUV) => {
|
|
5512
|
+
const idx = indexedPositions.length;
|
|
5513
|
+
const P = new Float64Array(5);
|
|
5514
|
+
P.set(p);
|
|
5515
|
+
if (addUV) {
|
|
5516
|
+
math.addVec3(planeToMesh, p, tempVec3a);
|
|
5517
|
+
P[3] = -math.dotVec3(planeU, tempVec3a);
|
|
5518
|
+
P[4] = math.dotVec3(planeV, tempVec3a);
|
|
5519
|
+
}
|
|
5520
|
+
indexedPositions.push(P);
|
|
5521
|
+
return idx;
|
|
5522
|
+
};
|
|
5517
5523
|
|
|
5518
|
-
|
|
5519
|
-
|
|
5524
|
+
const getCoord2D = (idx, dst) => { const P = indexedPositions[idx]; dst[0] = P[3]; dst[1] = P[4]; return dst; };
|
|
5525
|
+
|
|
5526
|
+
const isLoopInside = (inner, outer) => {
|
|
5527
|
+
const bbI = inner.boundingBox;
|
|
5528
|
+
const bbO = outer.boundingBox;
|
|
5529
|
+
if ((bbI[0] < bbO[0]) || (bbI[1] < bbO[1]) || (bbI[2] > bbO[2]) || (bbI[3] > bbO[3])) {
|
|
5530
|
+
return false;
|
|
5520
5531
|
}
|
|
5521
5532
|
|
|
5522
|
-
const
|
|
5523
|
-
const
|
|
5533
|
+
const innerEndpoints = inner.endPoints;
|
|
5534
|
+
const outerEndpoints = outer.endPoints;
|
|
5535
|
+
for (let ii = 0, ij = innerEndpoints.length - 1; ii < innerEndpoints.length; ij = ii++) {
|
|
5536
|
+
const i0 = getCoord2D(innerEndpoints[ii], tempVec2a);
|
|
5537
|
+
const [i0x, i0y] = i0;
|
|
5538
|
+
const i1 = getCoord2D(innerEndpoints[ij], tempVec2b);
|
|
5524
5539
|
|
|
5525
|
-
|
|
5526
|
-
|
|
5540
|
+
let inside = false;
|
|
5541
|
+
for (let i = 0, j = outerEndpoints.length - 1; i < outerEndpoints.length; j = i++) {
|
|
5542
|
+
const o0 = getCoord2D(outerEndpoints[i], tempVec2c);
|
|
5543
|
+
const o1 = getCoord2D(outerEndpoints[j], tempVec2d);
|
|
5527
5544
|
|
|
5528
|
-
|
|
5529
|
-
|
|
5545
|
+
if ((ccw(i0, o0, o1) !== ccw(i1, o0, o1)) && (ccw(i0, i1, o0) !== ccw(i0, i1, o1))) {
|
|
5546
|
+
return false; // segments intersect
|
|
5547
|
+
}
|
|
5530
5548
|
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
return false; // on edge
|
|
5534
|
-
}
|
|
5549
|
+
const [o0x, o0y] = o0;
|
|
5550
|
+
const [o1x, o1y] = o1;
|
|
5535
5551
|
|
|
5536
|
-
|
|
5537
|
-
|
|
5552
|
+
const dx = i0x - o0x;
|
|
5553
|
+
const dy = i0y - o0y;
|
|
5554
|
+
|
|
5555
|
+
const oDx = o1x - o0x;
|
|
5556
|
+
const oDy = o1y - o0y;
|
|
5557
|
+
|
|
5558
|
+
const dot = (((oDx !== 0) || (oDy !== 0)) && (Math.abs(oDx * dy - oDy * dx) < 1e-10)) ? (dx * oDx + dy * oDy) : -1;
|
|
5559
|
+
if ((dot >= 0) && (dot <= (Math.pow(oDx, 2) + Math.pow(oDy, 2)))) {
|
|
5560
|
+
return false; // on edge
|
|
5561
|
+
}
|
|
5562
|
+
|
|
5563
|
+
if (((o0y > i0y) !== (o1y > i0y)) && (dx < (dy * oDx / oDy))) {
|
|
5564
|
+
inside = !inside;
|
|
5565
|
+
}
|
|
5566
|
+
}
|
|
5567
|
+
if (! inside) {
|
|
5568
|
+
return false;
|
|
5569
|
+
}
|
|
5538
5570
|
}
|
|
5539
|
-
}
|
|
5540
|
-
if (! inside) {
|
|
5541
|
-
return false;
|
|
5542
|
-
}
|
|
5543
|
-
}
|
|
5544
5571
|
|
|
5545
|
-
|
|
5546
|
-
|
|
5572
|
+
return true;
|
|
5573
|
+
};
|
|
5547
5574
|
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
const planeV = math.vec3ApplyQuaternion(planeRot, worldUp, math.vec3());
|
|
5551
|
-
const planeN = math.vec3ApplyQuaternion(planeRot, worldForward, math.vec3());
|
|
5575
|
+
const pos = { indices: [ ], normals: [ ] };
|
|
5576
|
+
const neg = (! cfg.onlyPosSliceWithUV) && { indices: [ ], normals: [ ] };
|
|
5552
5577
|
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5578
|
+
const appendOnSide = (dst, indices, normal) => {
|
|
5579
|
+
if (dst) {
|
|
5580
|
+
const p0 = indexedPositions[indices[0]];
|
|
5581
|
+
normal ||= math.normalizeVec3(math.cross3Vec3(math.subVec3(indexedPositions[indices[1]], p0, tempVec3a),
|
|
5582
|
+
math.subVec3(indexedPositions[indices[2]], p0, tempVec3b),
|
|
5583
|
+
tempVec3a),
|
|
5584
|
+
tempVec3a);
|
|
5556
5585
|
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5586
|
+
for (let i = 0; i < 3; ++i) {
|
|
5587
|
+
dst.indices.push(indices[i]);
|
|
5588
|
+
dst.normals.push(normal[0], normal[1], normal[2]);
|
|
5589
|
+
}
|
|
5590
|
+
}
|
|
5591
|
+
};
|
|
5560
5592
|
|
|
5561
5593
|
const setVertex = (i, dst) => {
|
|
5562
|
-
const idx =
|
|
5563
|
-
dst[0] =
|
|
5564
|
-
dst[1] =
|
|
5565
|
-
dst[2] =
|
|
5594
|
+
const idx = mesh.indices[i] * 3;
|
|
5595
|
+
dst[0] = mesh.positions[idx + 0];
|
|
5596
|
+
dst[1] = mesh.positions[idx + 1];
|
|
5597
|
+
dst[2] = mesh.positions[idx + 2];
|
|
5566
5598
|
return dst;
|
|
5567
5599
|
};
|
|
5568
5600
|
|
|
5569
|
-
for (let
|
|
5570
|
-
const p0 = setVertex(
|
|
5571
|
-
const p1 = setVertex(
|
|
5572
|
-
const p2 = setVertex(
|
|
5601
|
+
for (let faceIdx = 0; faceIdx < mesh.indices.length; faceIdx += 3) {
|
|
5602
|
+
const p0 = setVertex(faceIdx + 0, triangle[0]);
|
|
5603
|
+
const p1 = setVertex(faceIdx + 1, triangle[1]);
|
|
5604
|
+
const p2 = setVertex(faceIdx + 2, triangle[2]);
|
|
5573
5605
|
|
|
5574
5606
|
if (math.compareVec3(p0, p1) || math.compareVec3(p1, p2) || math.compareVec3(p2, p0)) {
|
|
5575
5607
|
continue; // skip degenerate triangle
|
|
@@ -5580,12 +5612,60 @@ math.makeSectionPlaneSlicer = (function() {
|
|
|
5580
5612
|
const d2 = planeDist + math.dotVec3(planeN, p2);
|
|
5581
5613
|
|
|
5582
5614
|
if ((d0 !== 0) || (d1 !== 0) || (d2 !== 0)) {
|
|
5583
|
-
const i0 = (d0 * d1 <= 0) && addPosition(math.lerpVec3(d0 / (d0 - d1), 0, 1, p0, p1, tempVec3a));
|
|
5584
|
-
const i1 = (d1 * d2 <= 0) && addPosition(math.lerpVec3(d1 / (d1 - d2), 0, 1, p1, p2, tempVec3a));
|
|
5585
|
-
const i2 = (d2 * d0 <= 0) && addPosition(math.lerpVec3(d2 / (d2 - d0), 0, 1, p2, p0, tempVec3a));
|
|
5615
|
+
const i0 = (d0 * d1 <= 0) && addPosition(math.lerpVec3(d0 / (d0 - d1), 0, 1, p0, p1, tempVec3a), true);
|
|
5616
|
+
const i1 = (d1 * d2 <= 0) && addPosition(math.lerpVec3(d1 / (d1 - d2), 0, 1, p1, p2, tempVec3a), true);
|
|
5617
|
+
const i2 = (d2 * d0 <= 0) && addPosition(math.lerpVec3(d2 / (d2 - d0), 0, 1, p2, p0, tempVec3a), true);
|
|
5618
|
+
|
|
5619
|
+
const p = (! cfg.onlyPosSliceWithUV) && tmpPositions;
|
|
5620
|
+
if (p) {
|
|
5621
|
+
p[0] = addPosition(p0);
|
|
5622
|
+
p[1] = addPosition(p1);
|
|
5623
|
+
p[2] = addPosition(p2);
|
|
5624
|
+
}
|
|
5586
5625
|
|
|
5587
5626
|
if (i0 ? (i1 || i2) : (i1 && i2)) { // triangle intersected by the section plane
|
|
5588
5627
|
unsortedSegment.push(i0 ? [ i0, i1 || i2 ] : [ i1, i2 ]);
|
|
5628
|
+
|
|
5629
|
+
if (p) {
|
|
5630
|
+
if ((d0 === 0) && (d1 === 0)) {
|
|
5631
|
+
appendOnSide((d2 > 0) ? pos : neg, p);
|
|
5632
|
+
} else if ((d0 === 0) && (d2 === 0)) {
|
|
5633
|
+
appendOnSide((d1 > 0) ? pos : neg, p);
|
|
5634
|
+
} else if ((d1 === 0) && (d2 === 0)) {
|
|
5635
|
+
appendOnSide((d0 > 0) ? pos : neg, p);
|
|
5636
|
+
} else {
|
|
5637
|
+
const isPos = (i0 ? d0 : d1) > 0;
|
|
5638
|
+
const dst0 = isPos ? pos : neg;
|
|
5639
|
+
const dst1 = isPos ? neg : pos;
|
|
5640
|
+
const i = tmpIntersections;
|
|
5641
|
+
i[0] = i0;
|
|
5642
|
+
i[1] = i1;
|
|
5643
|
+
i[2] = i2;
|
|
5644
|
+
const ref = tmpReferences;
|
|
5645
|
+
if (i0) {
|
|
5646
|
+
ref[0] = 0; ref[1] = 1; ref[2] = 2;
|
|
5647
|
+
} else {
|
|
5648
|
+
ref[0] = 1; ref[1] = 2; ref[2] = 0;
|
|
5649
|
+
}
|
|
5650
|
+
if (i[ref[1]]) {
|
|
5651
|
+
appendOnSide(dst0, [ p[ref[0]], i[ref[0]], p[ref[2]] ]);
|
|
5652
|
+
appendOnSide(dst0, [ i[ref[0]], i[ref[1]], p[ref[2]] ]);
|
|
5653
|
+
appendOnSide(dst1, [ i[ref[0]], p[ref[1]], i[ref[1]] ]);
|
|
5654
|
+
} else {
|
|
5655
|
+
appendOnSide(dst0, [ p[ref[0]], i[ref[0]], i[ref[2]] ]);
|
|
5656
|
+
appendOnSide(dst1, [ i[ref[0]], p[ref[1]], p[ref[2]] ]);
|
|
5657
|
+
appendOnSide(dst1, [ i[ref[0]], p[ref[2]], i[ref[2]] ]);
|
|
5658
|
+
}
|
|
5659
|
+
}
|
|
5660
|
+
}
|
|
5661
|
+
} else if (p) {
|
|
5662
|
+
if ((d0 >= 0) && (d1 >= 0) && (d2 >= 0)) {
|
|
5663
|
+
appendOnSide(pos, p);
|
|
5664
|
+
} else if ((d0 <= 0) && (d1 <= 0) && (d2 <= 0)) {
|
|
5665
|
+
appendOnSide(neg, p);
|
|
5666
|
+
} else {
|
|
5667
|
+
debugger;
|
|
5668
|
+
}
|
|
5589
5669
|
}
|
|
5590
5670
|
}
|
|
5591
5671
|
}
|
|
@@ -5631,37 +5711,30 @@ math.makeSectionPlaneSlicer = (function() {
|
|
|
5631
5711
|
}
|
|
5632
5712
|
|
|
5633
5713
|
const loops = endpointLoops.filter(endPoints => endPoints.length > 2).map((endPoints, idx) => {
|
|
5634
|
-
const planeEndpoints = endPoints.map(posIdx => {
|
|
5635
|
-
const P = math.addVec3(planeToMesh, indexedPositions[posIdx], tempVec3a);
|
|
5636
|
-
return { posIdx: posIdx, coord2Dx: math.dotVec3(planeU, P), coord2Dy: math.dotVec3(planeV, P) };
|
|
5637
|
-
});
|
|
5638
5714
|
let doubleArea = 0;
|
|
5639
5715
|
const aabb = math.collapseAABB2(math.AABB2());
|
|
5640
|
-
for (let i = 0; i <
|
|
5641
|
-
|
|
5642
|
-
tempVec2a[0] = p0.coord2Dx;
|
|
5643
|
-
tempVec2a[1] = p0.coord2Dy;
|
|
5716
|
+
for (let i = 0; i < endPoints.length; i++) {
|
|
5717
|
+
getCoord2D(endPoints[i], tempVec2a);
|
|
5644
5718
|
math.expandAABB2Point2(aabb, tempVec2a);
|
|
5645
|
-
|
|
5646
|
-
doubleArea += (
|
|
5719
|
+
getCoord2D(endPoints[(i + 1) % endPoints.length], tempVec2b);
|
|
5720
|
+
doubleArea += (tempVec2a[0] * tempVec2b[1] - tempVec2b[0] * tempVec2a[1]);
|
|
5647
5721
|
}
|
|
5648
5722
|
return {
|
|
5649
5723
|
boundingBox: aabb,
|
|
5650
5724
|
doubleArea: Math.abs(doubleArea),
|
|
5651
|
-
endPoints:
|
|
5725
|
+
endPoints: endPoints
|
|
5652
5726
|
};
|
|
5653
5727
|
}).sort((a, b) => b.doubleArea - a.doubleArea);
|
|
5654
5728
|
|
|
5655
|
-
const sliceGeometries = [ ];
|
|
5656
|
-
|
|
5657
5729
|
while (loops.length > 0) {
|
|
5658
5730
|
const vertices2D = [ ];
|
|
5659
5731
|
const vertices3D = [ ];
|
|
5660
5732
|
|
|
5661
5733
|
const appendLoopVertices = loop => loop.endPoints.forEach(endpoint2D => {
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5734
|
+
getCoord2D(endpoint2D, tempVec2a);
|
|
5735
|
+
vertices2D.push(tempVec2a[0], tempVec2a[1]);
|
|
5736
|
+
vertices3D.push(endpoint2D);
|
|
5737
|
+
});
|
|
5665
5738
|
|
|
5666
5739
|
const outerLoop = loops.shift();
|
|
5667
5740
|
appendLoopVertices(outerLoop);
|
|
@@ -5683,41 +5756,33 @@ math.makeSectionPlaneSlicer = (function() {
|
|
|
5683
5756
|
// Triangulate
|
|
5684
5757
|
const triangles = earcut(vertices2D, innerLoops.map(loop => loop.index));
|
|
5685
5758
|
|
|
5686
|
-
const positions = [ ];
|
|
5687
|
-
const normals = [ ];
|
|
5688
|
-
const uv = [ ];
|
|
5689
5759
|
for (let i = 0; i < triangles.length; i += 3) {
|
|
5690
|
-
const
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5760
|
+
const ti = tmpIntersections;
|
|
5761
|
+
ti[0] = vertices3D[triangles[i + 0]];
|
|
5762
|
+
ti[1] = vertices3D[triangles[i + 1]];
|
|
5763
|
+
ti[2] = vertices3D[triangles[i + 2]];
|
|
5764
|
+
const v0 = indexedPositions[ti[0]];
|
|
5765
|
+
math.subVec3(indexedPositions[ti[1]], v0, tempVec3b);
|
|
5766
|
+
math.subVec3(indexedPositions[ti[2]], v0, tempVec3c);
|
|
5695
5767
|
math.normalizeVec3(math.cross3Vec3(tempVec3b, tempVec3c, tempVec3c), tempVec3c);
|
|
5696
5768
|
const facedPositively = math.dotVec3(tempVec3c, planeN) <= 0;
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
for (let j = 0; j < 3; ++j) {
|
|
5701
|
-
const vIdx = triangles[i + (facedPositively ? j : (2 - j))];
|
|
5702
|
-
const v = indexedPositions[vertices3D[vIdx]];
|
|
5703
|
-
positions.push(v[0], v[1], v[2]);
|
|
5704
|
-
normals.push(tempVec3c[0], tempVec3c[1], tempVec3c[2]);
|
|
5705
|
-
const uvOff = 2 * vIdx;
|
|
5706
|
-
uv.push(-vertices2D[uvOff], vertices2D[uvOff + 1]);
|
|
5707
|
-
}
|
|
5708
|
-
}
|
|
5709
|
-
|
|
5710
|
-
if (positions.length > 0) {
|
|
5711
|
-
sliceGeometries.push({
|
|
5712
|
-
indices: iota(positions.length / 3),
|
|
5713
|
-
positions: positions,
|
|
5714
|
-
normals: normals,
|
|
5715
|
-
uv: uv
|
|
5716
|
-
});
|
|
5769
|
+
appendOnSide(facedPositively ? pos : neg, ti, tempVec3c);
|
|
5770
|
+
const tmp = ti[0]; ti[0] = ti[2]; ti[2] = tmp;
|
|
5771
|
+
appendOnSide(facedPositively ? neg : pos, ti, math.negateVec3(tempVec3c, tempVec3c));
|
|
5717
5772
|
}
|
|
5718
5773
|
}
|
|
5719
5774
|
|
|
5720
|
-
|
|
5775
|
+
const side = src => src && (src.indices.length > 0) && (function() {
|
|
5776
|
+
const positions = [ ];
|
|
5777
|
+
const uv = cfg.onlyPosSliceWithUV && [ ];
|
|
5778
|
+
src.indices.forEach(idx => {
|
|
5779
|
+
const P = indexedPositions[idx];
|
|
5780
|
+
positions.push(P[0], P[1], P[2]);
|
|
5781
|
+
uv && uv.push(P[3], P[4]);
|
|
5782
|
+
});
|
|
5783
|
+
return { indices: iota(src.indices.length), positions: positions, normals: src.normals, uv: uv };
|
|
5784
|
+
})();
|
|
5785
|
+
return { pos: side(pos), neg: side(neg) };
|
|
5721
5786
|
};
|
|
5722
5787
|
};
|
|
5723
5788
|
})();
|
|
@@ -3337,34 +3337,37 @@ export class SceneModel extends Component {
|
|
|
3337
3337
|
/**
|
|
3338
3338
|
* @private
|
|
3339
3339
|
*/
|
|
3340
|
-
_withEachVisibleLayer(testNumVisibleLayerPortions, cb) {
|
|
3340
|
+
_withEachVisibleLayer(frameCtx, testNumVisibleLayerPortions, cb) {
|
|
3341
3341
|
if (testNumVisibleLayerPortions && (this.numVisibleLayerPortions === 0)) {
|
|
3342
3342
|
return;
|
|
3343
3343
|
}
|
|
3344
|
+
const testLayerCull = frameCtx.testAABB;
|
|
3344
3345
|
const renderFlags = this.renderFlags;
|
|
3345
3346
|
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3346
|
-
const
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3347
|
+
const layer = this.layerList[renderFlags.visibleLayers[i]];
|
|
3348
|
+
if ((! testLayerCull) || testLayerCull(layer.getAABB())) {
|
|
3349
|
+
cb(layer);
|
|
3350
|
+
}
|
|
3351
|
+
}
|
|
3352
|
+
}
|
|
3353
|
+
|
|
3354
|
+
drawColorOpaque (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawColorOpaque (this.renderFlags, frameCtx)); }
|
|
3355
|
+
drawColorTransparent (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawColorTransparent (this.renderFlags, frameCtx)); }
|
|
3356
|
+
drawDepth (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawDepth (this.renderFlags, frameCtx)); } // Dedicated to SAO because it skips transparent objects
|
|
3357
|
+
drawSilhouetteXRayed (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawSilhouetteXRayed (this.renderFlags, frameCtx)); }
|
|
3358
|
+
drawSilhouetteHighlighted(frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawSilhouetteHighlighted(this.renderFlags, frameCtx)); }
|
|
3359
|
+
drawSilhouetteSelected (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawSilhouetteSelected (this.renderFlags, frameCtx)); }
|
|
3360
|
+
drawEdgesColorOpaque (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawEdgesColorOpaque (this.renderFlags, frameCtx)); }
|
|
3361
|
+
drawEdgesColorTransparent(frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawEdgesColorTransparent(this.renderFlags, frameCtx)); }
|
|
3362
|
+
drawEdgesXRayed (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawEdgesXRayed (this.renderFlags, frameCtx)); }
|
|
3363
|
+
drawEdgesHighlighted (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawEdgesHighlighted (this.renderFlags, frameCtx)); }
|
|
3364
|
+
drawEdgesSelected (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawEdgesSelected (this.renderFlags, frameCtx)); }
|
|
3365
|
+
drawOcclusion (frameCtx) { this._withEachVisibleLayer(frameCtx, true, layer => layer.drawOcclusion (this.renderFlags, frameCtx)); }
|
|
3366
|
+
drawShadow (frameCtx) { this._withEachVisibleLayer(frameCtx, true, layer => layer.drawShadow (this.renderFlags, frameCtx)); }
|
|
3367
|
+
drawPickMesh (frameCtx) { this._withEachVisibleLayer(frameCtx, true, layer => layer.drawPickMesh (this.renderFlags, frameCtx)); }
|
|
3368
|
+
drawPickDepths (frameCtx) { this._withEachVisibleLayer(frameCtx, true, layer => layer.drawPickDepths (this.renderFlags, frameCtx)); }
|
|
3369
|
+
drawPickNormals (frameCtx) { this._withEachVisibleLayer(frameCtx, true, layer => layer.drawPickNormals (this.renderFlags, frameCtx)); }
|
|
3370
|
+
_drawSnap (frameCtx, isSnapInit) { this._withEachVisibleLayer(frameCtx, true, layer => layer.drawSnap (this.renderFlags, frameCtx, isSnapInit)); }
|
|
3368
3371
|
|
|
3369
3372
|
drawSnapInit(frameCtx) { this._drawSnap(frameCtx, true ); }
|
|
3370
3373
|
drawSnap (frameCtx) { this._drawSnap(frameCtx, false); }
|
|
@@ -12,9 +12,9 @@ function quantizePositions(positions, aabb, positionsDecodeMatrix) { // http://c
|
|
|
12
12
|
const xmin = aabb[0];
|
|
13
13
|
const ymin = aabb[1];
|
|
14
14
|
const zmin = aabb[2];
|
|
15
|
-
const xwid = aabb[3] - xmin;
|
|
16
|
-
const ywid = aabb[4] - ymin;
|
|
17
|
-
const zwid = aabb[5] - zmin;
|
|
15
|
+
const xwid = (aabb[3] - xmin) || 1;
|
|
16
|
+
const ywid = (aabb[4] - ymin) || 1;
|
|
17
|
+
const zwid = (aabb[5] - zmin) || 1;
|
|
18
18
|
const maxInt = 65525;
|
|
19
19
|
const xMultiplier = maxInt / xwid;
|
|
20
20
|
const yMultiplier = maxInt / ywid;
|
|
@@ -43,9 +43,9 @@ function createPositionsDecodeMatrix(aabb, positionsDecodeMatrix) { // http://cg
|
|
|
43
43
|
const xmin = aabb[0];
|
|
44
44
|
const ymin = aabb[1];
|
|
45
45
|
const zmin = aabb[2];
|
|
46
|
-
const xwid = aabb[3] - xmin;
|
|
47
|
-
const ywid = aabb[4] - ymin;
|
|
48
|
-
const zwid = aabb[5] - zmin;
|
|
46
|
+
const xwid = (aabb[3] - xmin) || 1;
|
|
47
|
+
const ywid = (aabb[4] - ymin) || 1;
|
|
48
|
+
const zwid = (aabb[5] - zmin) || 1;
|
|
49
49
|
const maxInt = 65525;
|
|
50
50
|
math.identityMat4(translate);
|
|
51
51
|
math.translationMat4v(aabb, translate);
|
|
@@ -812,9 +812,13 @@ const makeDTXRenderingAttributes = function(programVariables, isTriangle) {
|
|
|
812
812
|
const colorsAndFlags = (offset) => perObjColsFlags(`ivec2(objectIndexCoords.x*8+${offset}, objectIndexCoords.y)`);
|
|
813
813
|
|
|
814
814
|
return {
|
|
815
|
+
clippableTest: (function() {
|
|
816
|
+
const vClippable = programVariables.createVarying("uint", "vClippable", () => "flags2.r", "flat");
|
|
817
|
+
return () => `${vClippable} > 0u`;
|
|
818
|
+
})(),
|
|
819
|
+
|
|
815
820
|
geometryParameters: {
|
|
816
821
|
attributes: {
|
|
817
|
-
clippable: "(flags2.r > 0u)",
|
|
818
822
|
color: colorA,
|
|
819
823
|
flags: iota(4).map(i => `int(flags[${i}])`),
|
|
820
824
|
metallicRoughness: null,
|
|
@@ -156,10 +156,7 @@ export const getRenderers = (function() {
|
|
|
156
156
|
appendFragmentOutputs: programSetup.appendFragmentOutputs,
|
|
157
157
|
cleanerEdges: programSetup.cleanerEdges,
|
|
158
158
|
clipPos: clipPos,
|
|
159
|
-
clippableTest:
|
|
160
|
-
const vClippable = programVariables.createVarying("float", "vClippable", () => `${attributes.clippable} ? 1.0 : 0.0`, "flat");
|
|
161
|
-
return () => `${vClippable} > 0.0`;
|
|
162
|
-
})(),
|
|
159
|
+
clippableTest: renderingAttributes.clippableTest,
|
|
163
160
|
clippingCaps: programSetup.clippingCaps,
|
|
164
161
|
crossSections: scene.crossSections,
|
|
165
162
|
discardPoints: setupPoints && pointsMaterial.roundPoints,
|
|
@@ -505,6 +502,15 @@ export class Layer {
|
|
|
505
502
|
|
|
506
503
|
aabbChanged() { this._aabbDirty = true; }
|
|
507
504
|
|
|
505
|
+
getAABB() {
|
|
506
|
+
if (this._aabbDirty) { // Per-layer AABB for best RTC accuracy
|
|
507
|
+
math.collapseAABB3(this._aabb);
|
|
508
|
+
this._meshes.forEach(m => math.expandAABB3(this._aabb, m.aabb));
|
|
509
|
+
this._aabbDirty = false;
|
|
510
|
+
}
|
|
511
|
+
return this._aabb;
|
|
512
|
+
}
|
|
513
|
+
|
|
508
514
|
__drawLayer(renderFlags, frameCtx, renderer, pass) {
|
|
509
515
|
if ((this._countsByFlag[ENTITY_FLAGS.CULLED].count < this._portions.length) && (this._countsByFlag[ENTITY_FLAGS.VISIBLE].count > 0)) {
|
|
510
516
|
const backfacePasses = (this.primitive !== "points") && (this.primitive !== "lines") && [
|
|
@@ -674,13 +680,7 @@ export class Layer {
|
|
|
674
680
|
drawSnap(renderFlags, frameCtx, isSnapInit) {
|
|
675
681
|
frameCtx.snapPickOrigin = [0, 0, 0];
|
|
676
682
|
|
|
677
|
-
|
|
678
|
-
math.collapseAABB3(this._aabb);
|
|
679
|
-
this._meshes.forEach(m => math.expandAABB3(this._aabb, m.aabb));
|
|
680
|
-
this._aabbDirty = false;
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
const aabb = this._aabb;
|
|
683
|
+
const aabb = this.getAABB();
|
|
684
684
|
frameCtx.snapPickCoordinateScale = math.mulVec3Scalar(
|
|
685
685
|
safeInvVec3([ aabb[3] - aabb[0], aabb[4] - aabb[1], aabb[5] - aabb[2] ]),
|
|
686
686
|
math.MAX_INT);
|
|
@@ -887,8 +887,8 @@ export class VBOLayer extends Layer {
|
|
|
887
887
|
} else { // triangles
|
|
888
888
|
if (subGeometry && subGeometry.vertices) {
|
|
889
889
|
return drawPoints;
|
|
890
|
-
} else if (subGeometry
|
|
891
|
-
return elementsDrawer(gl.LINES, edgeIndicesBuf);
|
|
890
|
+
} else if (subGeometry) {
|
|
891
|
+
return edgeIndicesBuf ? elementsDrawer(gl.LINES, edgeIndicesBuf) : (() => { });
|
|
892
892
|
} else {
|
|
893
893
|
return elementsDrawer(gl.TRIANGLES, indicesBuf);
|
|
894
894
|
}
|
|
@@ -970,9 +970,13 @@ const makeVBORenderingAttributes = function(programVariables, instancing, entity
|
|
|
970
970
|
return {
|
|
971
971
|
dontCullOnAlphaZero: true,
|
|
972
972
|
|
|
973
|
+
clippableTest: (function() {
|
|
974
|
+
const vClippable = programVariables.createVarying("float", "vClippable", () => `${`((int(${attributes.flags}) >> 16 & 0xF) == 1)`} ? 1.0 : 0.0`); // Using `flat uint` for vClippable causes an instability - see XEOK-385
|
|
975
|
+
return () => `${vClippable} != 0.0`;
|
|
976
|
+
})(),
|
|
977
|
+
|
|
973
978
|
geometryParameters: {
|
|
974
979
|
attributes: {
|
|
975
|
-
clippable: `((int(${attributes.flags}) >> 16 & 0xF) == 1)`,
|
|
976
980
|
color: attributes.color,
|
|
977
981
|
flags: iota(4).map(i => ({ toString: () => `(int(${attributes.flags}) >> ${i * 4} & 0xF)` })),
|
|
978
982
|
metallicRoughness: attributes.metallicRoughness,
|
|
@@ -118,7 +118,7 @@ class SectionCaps {
|
|
|
118
118
|
const visibleSceneModels = Object.values(scene.models).filter(sceneModel => (sceneModel.id in modelCaches) && sceneModel.visible);
|
|
119
119
|
sectionPlanes.forEach((plane) => {
|
|
120
120
|
if (plane.active) {
|
|
121
|
-
const sliceMesh = math.makeSectionPlaneSlicer(plane
|
|
121
|
+
const sliceMesh = math.makeSectionPlaneSlicer(plane);
|
|
122
122
|
visibleSceneModels.forEach(sceneModel => {
|
|
123
123
|
const modelAABB = sceneModel.aabb;
|
|
124
124
|
if (math.planeIntersectsAABB3(plane, modelAABB)) {
|
|
@@ -138,10 +138,11 @@ class SectionCaps {
|
|
|
138
138
|
});
|
|
139
139
|
|
|
140
140
|
entityCache.meshCaches.filter(meshCache => math.planeIntersectsAABB3(plane, meshCache.mesh.aabb)).forEach((meshCache, meshIdx) => {
|
|
141
|
-
sliceMesh(modelCenter, meshCache.meshIndices, meshCache.meshVertices
|
|
141
|
+
const geo = sliceMesh({ origin: modelCenter, indices: meshCache.meshIndices, positions: meshCache.meshVertices }, { onlyPosSliceWithUV: true }).pos;
|
|
142
|
+
if (geo) {
|
|
142
143
|
entityCache.capMeshes.push(new Mesh(scene, {
|
|
143
144
|
isObject: true,
|
|
144
|
-
id: `${plane.id}-${entityId}-${meshIdx}
|
|
145
|
+
id: `${plane.id}-${entityId}-${meshIdx}`,
|
|
145
146
|
material: entity.capMaterial,
|
|
146
147
|
origin: math.addVec3(modelCenter, math.mulVec3Scalar(plane.dir, 0.001, tempVec3a), tempVec3a),
|
|
147
148
|
geometry: new ReadableGeometry(scene, {
|
|
@@ -152,7 +153,7 @@ class SectionCaps {
|
|
|
152
153
|
uv: geo.uv
|
|
153
154
|
})
|
|
154
155
|
}));
|
|
155
|
-
}
|
|
156
|
+
}
|
|
156
157
|
});
|
|
157
158
|
}
|
|
158
159
|
});
|