@xeokit/xeokit-sdk 2.6.28 → 2.6.30
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/README.md +1 -0
- package/dist/xeokit-sdk.cjs.js +1425 -649
- package/dist/xeokit-sdk.es.js +1420 -650
- package/dist/xeokit-sdk.es5.js +629 -552
- package/dist/xeokit-sdk.min.cjs.js +5 -5
- package/dist/xeokit-sdk.min.es.js +5 -5
- package/dist/xeokit-sdk.min.es5.js +4 -4
- package/package.json +1 -1
- package/src/extras/PointerCircle/PointerCircle.js +1 -1
- package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsMouseControl.js +22 -41
- package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsTouchControl.js +3 -18
- package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsMouseControl.js +20 -41
- package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsTouchControl.js +4 -20
- package/src/plugins/DistanceMeasurementsPlugin/index.js +1 -1
- package/src/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.js +2 -110
- package/src/plugins/GLTFLoaderPlugin/GLTFSceneModelLoader.js +252 -222
- package/src/plugins/StoreyViewsPlugin/StoreyViewsPlugin.js +31 -1
- package/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js +20 -8
- package/src/plugins/ZonesPlugin/ZonesPlugin.js +1939 -0
- package/src/plugins/ZonesPlugin/index.js +1 -1875
- package/src/viewer/Viewer.js +2 -2
- package/src/viewer/metadata/MetaScene.js +0 -2
- package/src/viewer/scene/math/MeshSurfaceArea.js +90 -0
- package/src/viewer/scene/math/MeshVolume.js +102 -0
- package/src/viewer/scene/math/index.js +3 -0
- package/src/viewer/scene/math/isTriangleMeshSolid.js +162 -0
- package/src/viewer/scene/math/math.js +8 -0
- package/src/viewer/scene/model/SceneModel.js +73 -34
- package/src/viewer/scene/model/SceneModelEntity.js +46 -1
- package/src/viewer/scene/model/SceneModelMesh.js +74 -1
- package/src/viewer/scene/model/SceneModelTextureSet.js +5 -0
- package/src/viewer/scene/model/dtx/lines/DTXLinesLayer.js +7 -1
- package/src/viewer/scene/model/dtx/triangles/DTXTrianglesLayer.js +77 -1
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapInitRenderer.js +8 -0
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapRenderer.js +8 -0
- package/src/viewer/scene/model/vbo/VBORenderer.js +10 -1
- package/src/viewer/scene/model/vbo/batching/lines/VBOBatchingLinesLayer.js +6 -1
- package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapRenderer.js +1 -1
- package/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsLayer.js +6 -1
- package/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesLayer.js +59 -18
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/Renderers.js +40 -12
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesBatchingRenderer.js +2 -3
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorTextureRenderer.js +25 -7
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapRenderer.js +1 -1
- package/src/viewer/scene/model/vbo/instancing/lines/VBOInstancingLinesLayer.js +6 -1
- package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapRenderer.js +1 -1
- package/src/viewer/scene/model/vbo/instancing/points/VBOInstancingPointsLayer.js +6 -1
- package/src/viewer/scene/model/vbo/instancing/triangles/VBOInstancingTrianglesLayer.js +48 -14
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/Renderers.js +74 -47
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorTextureRenderer.js +29 -14
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesInstancingRenderer.js +5 -4
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapRenderer.js +1 -1
- package/src/viewer/scene/scene/Scene.js +16 -5
- package/src/viewer/scene/webgl/occlusion/OcclusionLayer.js +1 -1
- package/src/viewer/scene/webgl/occlusion/OcclusionTester.js +1 -5
- package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurement.d.ts +7 -0
- package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsPlugin.d.ts +26 -1
- package/types/plugins/DistanceMeasurementsPlugin/index.d.ts +3 -1
package/src/viewer/Viewer.js
CHANGED
|
@@ -46,7 +46,7 @@ class Viewer {
|
|
|
46
46
|
* @throws {String} Throws an exception when both canvasId or canvasElement are missing or they aren't pointing to a valid HTMLCanvasElement.
|
|
47
47
|
* @param {Boolean} [cfg.alphaDepthMask=true] Whether writing into the depth buffer is enabled or disabled when rendering transparent objects.
|
|
48
48
|
* @param {Boolean} [cfg.entityOffsetsEnabled=false] Whether to enable {@link Entity#offset}. For best performance, only set this ````true```` when you need to use {@link Entity#offset}.
|
|
49
|
-
* @param {Boolean} [cfg.
|
|
49
|
+
* @param {Boolean} [cfg.readableGeometryEnabled=false] Whether to enable full-precision accuracy when surface picking with {@link Scene#pick}. Note that when ````true````, this configuration will increase the amount of browser memory used by the Viewer. The ````pickSurfacePrecision```` option for ````Scene#pick```` only works if this is set ````true````.
|
|
50
50
|
* @param {Boolean} [cfg.logarithmicDepthBufferEnabled=false] Whether to enable logarithmic depth buffer. When this is true,
|
|
51
51
|
* you can set huge values for {@link Perspective#far} and {@link Ortho#far}, to push the far clipping plane back so
|
|
52
52
|
* that it does not clip huge models.
|
|
@@ -116,7 +116,7 @@ class Viewer {
|
|
|
116
116
|
saoEnabled: cfg.saoEnabled,
|
|
117
117
|
alphaDepthMask: (cfg.alphaDepthMask !== false),
|
|
118
118
|
entityOffsetsEnabled: (!!cfg.entityOffsetsEnabled),
|
|
119
|
-
|
|
119
|
+
readableGeometryEnabled: (!!cfg.readableGeometryEnabled),
|
|
120
120
|
logarithmicDepthBufferEnabled: (!!cfg.logarithmicDepthBufferEnabled),
|
|
121
121
|
pbrEnabled: (!!cfg.pbrEnabled),
|
|
122
122
|
colorTextureEnabled: (cfg.colorTextureEnabled !== false),
|
|
@@ -126,8 +126,6 @@ class MetaScene {
|
|
|
126
126
|
* @param {String} modelId ID for the new {@link MetaModel}, which will have {@link MetaModel#id} set to this value.
|
|
127
127
|
* @param {Object} metaModelData Data for the {@link MetaModel}.
|
|
128
128
|
* @param {Object} [options] Options for creating the {@link MetaModel}.
|
|
129
|
-
* @param {Object} [options.includeTypes] When provided, only create {@link MetaObject}s with types in this list.
|
|
130
|
-
* @param {Object} [options.excludeTypes] When provided, never create {@link MetaObject}s with types in this list.
|
|
131
129
|
* @param {Boolean} [options.globalizeObjectIds=false] Whether to globalize each {@link MetaObject#id}. Set this ````true```` when you need to load multiple instances of the same meta model, to avoid ID clashes between the meta objects in the different instances.
|
|
132
130
|
* @returns {MetaModel} The new MetaModel.
|
|
133
131
|
*/
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import {math} from "./math.js";
|
|
2
|
+
|
|
3
|
+
const v1 = math.vec3();
|
|
4
|
+
const v2 = math.vec3();
|
|
5
|
+
const v3 = math.vec3();
|
|
6
|
+
const v4 = math.vec3();
|
|
7
|
+
const v5 = math.vec3();
|
|
8
|
+
const v6 = math.vec3();
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Calculates the surface area of triangle meshes.
|
|
12
|
+
*/
|
|
13
|
+
export class MeshSurfaceArea {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.vertices = [];
|
|
16
|
+
this.indices = [];
|
|
17
|
+
this.reset();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Resets, ready to add vertices and indices for a new mesh.
|
|
22
|
+
*/
|
|
23
|
+
reset() {
|
|
24
|
+
this.lenVertices = 0;
|
|
25
|
+
this.lenIndices = 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Adds a vertex.
|
|
30
|
+
* @param vertex
|
|
31
|
+
*/
|
|
32
|
+
addVertex(vertex) {
|
|
33
|
+
this.vertices[this.lenVertices++] = vertex[0];
|
|
34
|
+
this.vertices[this.lenVertices++] = vertex[1];
|
|
35
|
+
this.vertices[this.lenVertices++] = vertex[2];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Adds an index.
|
|
40
|
+
* @param index
|
|
41
|
+
*/
|
|
42
|
+
addIndex(index) {
|
|
43
|
+
this.indices[this.lenIndices++] = index;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Gets the surface area of the mesh.
|
|
48
|
+
*
|
|
49
|
+
* @returns {number}
|
|
50
|
+
*/
|
|
51
|
+
get surfaceArea() {
|
|
52
|
+
|
|
53
|
+
const vertices = this.vertices;
|
|
54
|
+
const indices = this.indices;
|
|
55
|
+
|
|
56
|
+
let surfaceArea = 0;
|
|
57
|
+
|
|
58
|
+
for (let i = 0; i < this.lenIndices; i += 3) {
|
|
59
|
+
|
|
60
|
+
const index1 = indices[i] * 3;
|
|
61
|
+
const index2 = indices[i + 1] * 3;
|
|
62
|
+
const index3 = indices[i + 2] * 3;
|
|
63
|
+
|
|
64
|
+
v1[0] = vertices[index1];
|
|
65
|
+
v1[1] = vertices[index1 + 1];
|
|
66
|
+
v1[2] = vertices[index1 + 2];
|
|
67
|
+
|
|
68
|
+
v2[0] = vertices[index2];
|
|
69
|
+
v2[1] = vertices[index2 + 1];
|
|
70
|
+
v2[2] = vertices[index2 + 2];
|
|
71
|
+
|
|
72
|
+
v3[0] = vertices[index3];
|
|
73
|
+
v3[1] = vertices[index3 + 1];
|
|
74
|
+
v3[2] = vertices[index3 + 2];
|
|
75
|
+
|
|
76
|
+
math.subVec3(v1, v2, v4);
|
|
77
|
+
math.subVec3(v3, v2, v5);
|
|
78
|
+
|
|
79
|
+
surfaceArea += math.lenVec3(math.cross3Vec3(v4, v5, v6)) * 0.5;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return surfaceArea;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Singleton instance of {@link MeshSurfaceArea}.
|
|
88
|
+
* @type {MeshSurfaceArea}
|
|
89
|
+
*/
|
|
90
|
+
export const meshSurfaceArea = new MeshSurfaceArea();
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import {math} from "./math.js";
|
|
2
|
+
import {isTriangleMeshSolid} from "./isTriangleMeshSolid.js";
|
|
3
|
+
|
|
4
|
+
const v1 = math.vec3();
|
|
5
|
+
const v2 = math.vec3();
|
|
6
|
+
const v3 = math.vec3();
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Calculates the volume of triangle meshes.
|
|
10
|
+
*/
|
|
11
|
+
export class MeshVolume {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.vertices = [];
|
|
14
|
+
this.indices = [];
|
|
15
|
+
this.reset();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Resets, ready to add vertices and indices for a new mesh.
|
|
20
|
+
*/
|
|
21
|
+
reset() {
|
|
22
|
+
this.lenVertices = 0;
|
|
23
|
+
this.lenIndices = 0;
|
|
24
|
+
this.primitive = null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setPrimitive(primitive) {
|
|
28
|
+
this.primitive = primitive;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Adds a vertex.
|
|
33
|
+
* @param vertex
|
|
34
|
+
*/
|
|
35
|
+
addVertex(vertex) {
|
|
36
|
+
this.vertices[this.lenVertices++] = vertex[0];
|
|
37
|
+
this.vertices[this.lenVertices++] = vertex[1];
|
|
38
|
+
this.vertices[this.lenVertices++] = vertex[2];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Adds an index.
|
|
43
|
+
* @param index
|
|
44
|
+
*/
|
|
45
|
+
addIndex(index) {
|
|
46
|
+
this.indices[this.lenIndices++] = index;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Gets the volume of the mesh.
|
|
51
|
+
*
|
|
52
|
+
* The mesh must be a closed solid.
|
|
53
|
+
*
|
|
54
|
+
* @returns {number} The volume of the mesh, or -1 if the mesh is not solid, in which case volume cannot be determined.
|
|
55
|
+
*/
|
|
56
|
+
get volume() {
|
|
57
|
+
|
|
58
|
+
const vertices = this.vertices;
|
|
59
|
+
const indices = this.indices;
|
|
60
|
+
|
|
61
|
+
if (this.primitive !== "solid" && this.primitive !== "surface" && this.primitive !== "triangles") {
|
|
62
|
+
return -1;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (this.primitive !== "solid" && !isTriangleMeshSolid(indices, vertices)) {
|
|
66
|
+
return -1;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let volume = 0;
|
|
70
|
+
|
|
71
|
+
for (let i = 0; i < this.lenIndices; i += 3) {
|
|
72
|
+
|
|
73
|
+
const index1 = indices[i] * 3;
|
|
74
|
+
const index2 = indices[i + 1] * 3;
|
|
75
|
+
const index3 = indices[i + 2] * 3;
|
|
76
|
+
|
|
77
|
+
v1[0] = vertices[index1];
|
|
78
|
+
v1[1] = vertices[index1 + 1];
|
|
79
|
+
v1[2] = vertices[index1 + 2];
|
|
80
|
+
|
|
81
|
+
v2[0] = vertices[index2];
|
|
82
|
+
v2[1] = vertices[index2 + 1];
|
|
83
|
+
v2[2] = vertices[index2 + 2];
|
|
84
|
+
|
|
85
|
+
v3[0] = vertices[index3];
|
|
86
|
+
v3[1] = vertices[index3 + 1];
|
|
87
|
+
v3[2] = vertices[index3 + 2];
|
|
88
|
+
|
|
89
|
+
math.cross3Vec3(v1, v2, v1);
|
|
90
|
+
|
|
91
|
+
volume += math.dotVec3(v1, v3);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return volume;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Singleton instance of {@link MeshVolume}.
|
|
100
|
+
* @type {MeshVolume}
|
|
101
|
+
*/
|
|
102
|
+
export const meshVolume = new MeshVolume();
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Uses edge adjacency counts to identify if the given triangle mesh can be rendered with backface culling enabled.
|
|
3
|
+
*
|
|
4
|
+
* If all edges are connected to exactly two triangles, then the mesh will likely be a closed solid, and we can safely
|
|
5
|
+
* render it with backface culling enabled.
|
|
6
|
+
*
|
|
7
|
+
* Otherwise, the mesh is a surface, and we must render it with backface culling disabled.
|
|
8
|
+
*
|
|
9
|
+
* @private
|
|
10
|
+
*/
|
|
11
|
+
const isTriangleMeshSolid = (indices, positions) => {
|
|
12
|
+
|
|
13
|
+
const vertexIndexMapping = [];
|
|
14
|
+
let edges = [];
|
|
15
|
+
|
|
16
|
+
function compareIndexPositions(a, b) {
|
|
17
|
+
let posA, posB;
|
|
18
|
+
|
|
19
|
+
for (let i = 0; i < 3; i++) {
|
|
20
|
+
posA = positions [a * 3 + i];
|
|
21
|
+
posB = positions [b * 3 + i];
|
|
22
|
+
|
|
23
|
+
if (posA !== posB) {
|
|
24
|
+
return posB - posA;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return 0;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// Group together indices corresponding to same position coordinates
|
|
32
|
+
let newIndices = indices.slice().sort(compareIndexPositions);
|
|
33
|
+
|
|
34
|
+
// Calculate the mapping:
|
|
35
|
+
// - from original index in indices array
|
|
36
|
+
// - to indices-for-unique-positions
|
|
37
|
+
let uniqueVertexIndex = null;
|
|
38
|
+
|
|
39
|
+
for (let i = 0, len = newIndices.length; i < len; i++) {
|
|
40
|
+
if (i === 0 || 0 !== compareIndexPositions(
|
|
41
|
+
newIndices[i],
|
|
42
|
+
newIndices[i - 1],
|
|
43
|
+
)) {
|
|
44
|
+
// different position
|
|
45
|
+
uniqueVertexIndex = newIndices [i];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
vertexIndexMapping [
|
|
49
|
+
newIndices[i]
|
|
50
|
+
] = uniqueVertexIndex;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Generate the list of edges
|
|
54
|
+
for (let i = 0, len = indices.length; i < len; i += 3) {
|
|
55
|
+
|
|
56
|
+
const a = vertexIndexMapping[indices[i]];
|
|
57
|
+
const b = vertexIndexMapping[indices[i + 1]];
|
|
58
|
+
const c = vertexIndexMapping[indices[i + 2]];
|
|
59
|
+
|
|
60
|
+
let a2 = a;
|
|
61
|
+
let b2 = b;
|
|
62
|
+
let c2 = c;
|
|
63
|
+
|
|
64
|
+
if (a > b && a > c) {
|
|
65
|
+
if (b > c) {
|
|
66
|
+
a2 = a;
|
|
67
|
+
b2 = b;
|
|
68
|
+
c2 = c;
|
|
69
|
+
} else {
|
|
70
|
+
a2 = a;
|
|
71
|
+
b2 = c;
|
|
72
|
+
c2 = b;
|
|
73
|
+
}
|
|
74
|
+
} else if (b > a && b > c) {
|
|
75
|
+
if (a > c) {
|
|
76
|
+
a2 = b;
|
|
77
|
+
b2 = a;
|
|
78
|
+
c2 = c;
|
|
79
|
+
} else {
|
|
80
|
+
a2 = b;
|
|
81
|
+
b2 = c;
|
|
82
|
+
c2 = a;
|
|
83
|
+
}
|
|
84
|
+
} else if (c > a && c > b) {
|
|
85
|
+
if (a > b) {
|
|
86
|
+
a2 = c;
|
|
87
|
+
b2 = a;
|
|
88
|
+
c2 = b;
|
|
89
|
+
} else {
|
|
90
|
+
a2 = c;
|
|
91
|
+
b2 = b;
|
|
92
|
+
c2 = a;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
edges[i + 0] = [
|
|
97
|
+
a2, b2
|
|
98
|
+
];
|
|
99
|
+
edges[i + 1] = [
|
|
100
|
+
b2, c2
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
if (a2 > c2) {
|
|
104
|
+
const temp = c2;
|
|
105
|
+
c2 = a2;
|
|
106
|
+
a2 = temp;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
edges[i + 2] = [
|
|
110
|
+
c2, a2
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Group semantically equivalent edgdes together
|
|
115
|
+
function compareEdges(e1, e2) {
|
|
116
|
+
let a, b;
|
|
117
|
+
|
|
118
|
+
for (let i = 0; i < 2; i++) {
|
|
119
|
+
a = e1[i];
|
|
120
|
+
b = e2[i];
|
|
121
|
+
|
|
122
|
+
if (b !== a) {
|
|
123
|
+
return b - a;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
edges = edges.slice(0, indices.length);
|
|
131
|
+
|
|
132
|
+
edges.sort(compareEdges);
|
|
133
|
+
|
|
134
|
+
// Make sure each edge is used exactly twice
|
|
135
|
+
let sameEdgeCount = 0;
|
|
136
|
+
|
|
137
|
+
for (let i = 0; i < edges.length; i++) {
|
|
138
|
+
if (i === 0 || 0 !== compareEdges(
|
|
139
|
+
edges[i], edges[i - 1]
|
|
140
|
+
)) {
|
|
141
|
+
// different edge
|
|
142
|
+
if (0 !== i && sameEdgeCount !== 2) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
sameEdgeCount = 1;
|
|
147
|
+
} else {
|
|
148
|
+
// same edge
|
|
149
|
+
sameEdgeCount++;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (edges.length > 0 && sameEdgeCount !== 2) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Each edge is used exactly twice, this is a
|
|
158
|
+
// watertight surface and hence a solid geometry.
|
|
159
|
+
return true;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export {isTriangleMeshSolid};
|
|
@@ -3998,6 +3998,14 @@ const math = {
|
|
|
3998
3998
|
return aabb[0] > p[0] || aabb[3] < p[0] || aabb[1] > p[1] || aabb[4] < p[1] || aabb[2] > p[2] || aabb[5] < p[2];
|
|
3999
3999
|
},
|
|
4000
4000
|
|
|
4001
|
+
point3AABB3AbsoluteIntersect(aabb, p) {
|
|
4002
|
+
return (
|
|
4003
|
+
aabb[0] <= p[0] && aabb[3] >= p[0] &&
|
|
4004
|
+
aabb[1] <= p[1] && aabb[4] >= p[1] &&
|
|
4005
|
+
aabb[2] <= p[2] && aabb[5] >= p[2]
|
|
4006
|
+
);
|
|
4007
|
+
},
|
|
4008
|
+
|
|
4001
4009
|
/**
|
|
4002
4010
|
*
|
|
4003
4011
|
* @param dir
|
|
@@ -1155,7 +1155,10 @@ export class SceneModel extends Component {
|
|
|
1155
1155
|
this._meshList = [];
|
|
1156
1156
|
|
|
1157
1157
|
this.layerList = []; // For GL state efficiency when drawing, InstancingLayers are in first part, BatchingLayers are in second
|
|
1158
|
+
this._layersToFinalize = [];
|
|
1159
|
+
|
|
1158
1160
|
this._entityList = [];
|
|
1161
|
+
this._entitiesToFinalize = [];
|
|
1159
1162
|
|
|
1160
1163
|
this._geometries = {};
|
|
1161
1164
|
this._dtxBuckets = {}; // Geometries with optimizations used for data texture representation
|
|
@@ -1231,6 +1234,7 @@ export class SceneModel extends Component {
|
|
|
1231
1234
|
this._numTriangles = 0;
|
|
1232
1235
|
this._numLines = 0;
|
|
1233
1236
|
this._numPoints = 0;
|
|
1237
|
+
this._layersFinalized = false;
|
|
1234
1238
|
|
|
1235
1239
|
this._edgeThreshold = cfg.edgeThreshold || 10;
|
|
1236
1240
|
|
|
@@ -2640,6 +2644,7 @@ export class SceneModel extends Component {
|
|
|
2640
2644
|
id: textureSetId,
|
|
2641
2645
|
model: this,
|
|
2642
2646
|
colorTexture,
|
|
2647
|
+
alphaCutoff: cfg.alphaCutoff,
|
|
2643
2648
|
metallicRoughnessTexture,
|
|
2644
2649
|
normalsTexture,
|
|
2645
2650
|
emissiveTexture,
|
|
@@ -3073,6 +3078,14 @@ export class SceneModel extends Component {
|
|
|
3073
3078
|
return this._createMesh(cfg);
|
|
3074
3079
|
}
|
|
3075
3080
|
|
|
3081
|
+
_createDefaultIndices(numIndices) {
|
|
3082
|
+
const indices = [];
|
|
3083
|
+
for (let i = 0; i < numIndices; i++) {
|
|
3084
|
+
indices.push(i);
|
|
3085
|
+
}
|
|
3086
|
+
return indices;
|
|
3087
|
+
}
|
|
3088
|
+
|
|
3076
3089
|
_createMesh(cfg) {
|
|
3077
3090
|
const mesh = new SceneModelMesh(this, cfg.id, cfg.color, cfg.opacity, cfg.transform, cfg.textureSet);
|
|
3078
3091
|
mesh.pickId = this.scene._renderer.getPickID(mesh);
|
|
@@ -3172,7 +3185,7 @@ export class SceneModel extends Component {
|
|
|
3172
3185
|
let dtxLayer = this._dtxLayers[layerId];
|
|
3173
3186
|
if (dtxLayer) {
|
|
3174
3187
|
if (!dtxLayer.canCreatePortion(cfg)) {
|
|
3175
|
-
dtxLayer.finalize();
|
|
3188
|
+
// dtxLayer.finalize();
|
|
3176
3189
|
delete this._dtxLayers[layerId];
|
|
3177
3190
|
dtxLayer = null;
|
|
3178
3191
|
} else {
|
|
@@ -3183,16 +3196,17 @@ export class SceneModel extends Component {
|
|
|
3183
3196
|
case "triangles":
|
|
3184
3197
|
case "solid":
|
|
3185
3198
|
case "surface":
|
|
3186
|
-
dtxLayer = new DTXTrianglesLayer(this, {layerIndex: 0, origin}); // layerIndex is set in #finalize()
|
|
3199
|
+
dtxLayer = new DTXTrianglesLayer(this, {layerIndex: 0, origin, primitive}); // layerIndex is set in #finalize()
|
|
3187
3200
|
break;
|
|
3188
3201
|
case "lines":
|
|
3189
|
-
dtxLayer = new DTXLinesLayer(this, {layerIndex: 0, origin}); // layerIndex is set in #finalize()
|
|
3202
|
+
dtxLayer = new DTXLinesLayer(this, {layerIndex: 0, origin, primitive}); // layerIndex is set in #finalize()
|
|
3190
3203
|
break;
|
|
3191
3204
|
default:
|
|
3192
3205
|
return;
|
|
3193
3206
|
}
|
|
3194
3207
|
this._dtxLayers[layerId] = dtxLayer;
|
|
3195
3208
|
this.layerList.push(dtxLayer);
|
|
3209
|
+
this._layersToFinalize.push(dtxLayer);
|
|
3196
3210
|
return dtxLayer;
|
|
3197
3211
|
}
|
|
3198
3212
|
|
|
@@ -3224,7 +3238,8 @@ export class SceneModel extends Component {
|
|
|
3224
3238
|
origin,
|
|
3225
3239
|
maxGeometryBatchSize: this._maxGeometryBatchSize,
|
|
3226
3240
|
solid: (cfg.primitive === "solid"),
|
|
3227
|
-
autoNormals: true
|
|
3241
|
+
autoNormals: true,
|
|
3242
|
+
primitive: cfg.primitive
|
|
3228
3243
|
});
|
|
3229
3244
|
break;
|
|
3230
3245
|
case "solid":
|
|
@@ -3239,7 +3254,8 @@ export class SceneModel extends Component {
|
|
|
3239
3254
|
origin,
|
|
3240
3255
|
maxGeometryBatchSize: this._maxGeometryBatchSize,
|
|
3241
3256
|
solid: (cfg.primitive === "solid"),
|
|
3242
|
-
autoNormals: true
|
|
3257
|
+
autoNormals: true,
|
|
3258
|
+
primitive: cfg.primitive
|
|
3243
3259
|
});
|
|
3244
3260
|
break;
|
|
3245
3261
|
case "surface":
|
|
@@ -3254,7 +3270,8 @@ export class SceneModel extends Component {
|
|
|
3254
3270
|
origin,
|
|
3255
3271
|
maxGeometryBatchSize: this._maxGeometryBatchSize,
|
|
3256
3272
|
solid: (cfg.primitive === "solid"),
|
|
3257
|
-
autoNormals: true
|
|
3273
|
+
autoNormals: true,
|
|
3274
|
+
primitive: cfg.primitive
|
|
3258
3275
|
});
|
|
3259
3276
|
break;
|
|
3260
3277
|
case "lines":
|
|
@@ -3266,7 +3283,8 @@ export class SceneModel extends Component {
|
|
|
3266
3283
|
positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
|
|
3267
3284
|
uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
|
|
3268
3285
|
origin,
|
|
3269
|
-
maxGeometryBatchSize: this._maxGeometryBatchSize
|
|
3286
|
+
maxGeometryBatchSize: this._maxGeometryBatchSize,
|
|
3287
|
+
primitive: cfg.primitive
|
|
3270
3288
|
});
|
|
3271
3289
|
break;
|
|
3272
3290
|
case "points":
|
|
@@ -3278,7 +3296,8 @@ export class SceneModel extends Component {
|
|
|
3278
3296
|
positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
|
|
3279
3297
|
uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
|
|
3280
3298
|
origin,
|
|
3281
|
-
maxGeometryBatchSize: this._maxGeometryBatchSize
|
|
3299
|
+
maxGeometryBatchSize: this._maxGeometryBatchSize,
|
|
3300
|
+
primitive: cfg.primitive
|
|
3282
3301
|
});
|
|
3283
3302
|
break;
|
|
3284
3303
|
}
|
|
@@ -3294,6 +3313,7 @@ export class SceneModel extends Component {
|
|
|
3294
3313
|
}
|
|
3295
3314
|
this._vboBatchingLayers[layerId] = vboBatchingLayer;
|
|
3296
3315
|
this.layerList.push(vboBatchingLayer);
|
|
3316
|
+
this._layersToFinalize.push(vboBatchingLayer);
|
|
3297
3317
|
return vboBatchingLayer;
|
|
3298
3318
|
}
|
|
3299
3319
|
|
|
@@ -3386,6 +3406,7 @@ export class SceneModel extends Component {
|
|
|
3386
3406
|
}
|
|
3387
3407
|
this._vboInstancingLayers[layerId] = vboInstancingLayer;
|
|
3388
3408
|
this.layerList.push(vboInstancingLayer);
|
|
3409
|
+
this._layersToFinalize.push(vboInstancingLayer);
|
|
3389
3410
|
return vboInstancingLayer;
|
|
3390
3411
|
}
|
|
3391
3412
|
|
|
@@ -3486,38 +3507,47 @@ export class SceneModel extends Component {
|
|
|
3486
3507
|
lodCullable); // Internally sets SceneModelEntity#parent to this SceneModel
|
|
3487
3508
|
this._entityList.push(entity);
|
|
3488
3509
|
this._entities[cfg.id] = entity;
|
|
3510
|
+
this._entitiesToFinalize.push(entity);
|
|
3489
3511
|
this.numEntities++;
|
|
3490
3512
|
}
|
|
3491
3513
|
|
|
3492
3514
|
/**
|
|
3493
|
-
*
|
|
3494
|
-
*
|
|
3495
|
-
*
|
|
3515
|
+
* Pre-renders all meshes that have been added, even if the SceneModel has not bee finalized yet.
|
|
3516
|
+
* This is use for progressively showing the SceneModel while it is being loaded or constructed.
|
|
3517
|
+
* @returns {boolean}
|
|
3496
3518
|
*/
|
|
3497
|
-
|
|
3519
|
+
preFinalize() {
|
|
3498
3520
|
if (this.destroyed) {
|
|
3499
|
-
return;
|
|
3521
|
+
return false;
|
|
3522
|
+
}
|
|
3523
|
+
if (this._layersToFinalize.length === 0) {
|
|
3524
|
+
return false;
|
|
3500
3525
|
}
|
|
3501
3526
|
this._createDummyEntityForUnusedMeshes();
|
|
3502
|
-
for (let i = 0, len = this.
|
|
3503
|
-
const layer = this.
|
|
3527
|
+
for (let i = 0, len = this._layersToFinalize.length; i < len; i++) {
|
|
3528
|
+
const layer = this._layersToFinalize[i];
|
|
3504
3529
|
layer.finalize();
|
|
3505
3530
|
}
|
|
3506
|
-
this._geometries = {};
|
|
3507
|
-
this._dtxBuckets = {};
|
|
3508
|
-
this._textures = {};
|
|
3509
|
-
this._textureSets = {};
|
|
3510
|
-
this._dtxLayers = {};
|
|
3511
|
-
this._vboInstancingLayers = {};
|
|
3512
3531
|
this._vboBatchingLayers = {};
|
|
3513
|
-
|
|
3514
|
-
|
|
3532
|
+
this._vboInstancingLayers = {};
|
|
3533
|
+
this._dtxLayers = {};
|
|
3534
|
+
this._layersToFinalize = [];
|
|
3535
|
+
for (let i = 0, len = this._entitiesToFinalize.length; i < len; i++) {
|
|
3536
|
+
const entity = this._entitiesToFinalize[i];
|
|
3515
3537
|
entity._finalize();
|
|
3516
3538
|
}
|
|
3517
|
-
for (let i = 0, len = this.
|
|
3518
|
-
const entity = this.
|
|
3539
|
+
for (let i = 0, len = this._entitiesToFinalize.length; i < len; i++) {
|
|
3540
|
+
const entity = this._entitiesToFinalize[i];
|
|
3519
3541
|
entity._finalize2();
|
|
3520
3542
|
}
|
|
3543
|
+
this._entitiesToFinalize = [];
|
|
3544
|
+
this.scene._aabbDirty = true;
|
|
3545
|
+
this._viewMatrixDirty = true;
|
|
3546
|
+
this._matrixDirty = true;
|
|
3547
|
+
this._aabbDirty = true;
|
|
3548
|
+
this._setWorldMatrixDirty();
|
|
3549
|
+
this._sceneModelDirty();
|
|
3550
|
+
this.position = this._position;
|
|
3521
3551
|
// Sort layers to reduce WebGL shader switching when rendering them
|
|
3522
3552
|
this.layerList.sort((a, b) => {
|
|
3523
3553
|
if (a.sortId < b.sortId) {
|
|
@@ -3533,15 +3563,23 @@ export class SceneModel extends Component {
|
|
|
3533
3563
|
layer.layerIndex = i;
|
|
3534
3564
|
}
|
|
3535
3565
|
this.glRedraw();
|
|
3536
|
-
this.
|
|
3537
|
-
|
|
3538
|
-
this._matrixDirty = true;
|
|
3539
|
-
this._aabbDirty = true;
|
|
3540
|
-
|
|
3541
|
-
this._setWorldMatrixDirty();
|
|
3542
|
-
this._sceneModelDirty();
|
|
3566
|
+
this._layersFinalized = true;
|
|
3567
|
+
}
|
|
3543
3568
|
|
|
3544
|
-
|
|
3569
|
+
/**
|
|
3570
|
+
* Finalizes this SceneModel.
|
|
3571
|
+
*
|
|
3572
|
+
* Once finalized, you can't add anything more to this SceneModel.
|
|
3573
|
+
*/
|
|
3574
|
+
finalize() {
|
|
3575
|
+
if (this.destroyed) {
|
|
3576
|
+
return;
|
|
3577
|
+
}
|
|
3578
|
+
this.preFinalize();
|
|
3579
|
+
this._geometries = {};
|
|
3580
|
+
this._dtxBuckets = {};
|
|
3581
|
+
this._textures = {};
|
|
3582
|
+
this._textureSets = {};
|
|
3545
3583
|
}
|
|
3546
3584
|
|
|
3547
3585
|
/** @private */
|
|
@@ -3579,7 +3617,7 @@ export class SceneModel extends Component {
|
|
|
3579
3617
|
_createDummyEntityForUnusedMeshes() {
|
|
3580
3618
|
const unusedMeshIds = Object.keys(this._unusedMeshes);
|
|
3581
3619
|
if (unusedMeshIds.length > 0) {
|
|
3582
|
-
const entityId = `${this.id}
|
|
3620
|
+
const entityId = `${this.id}-${math.createUUID()}`;
|
|
3583
3621
|
this.warn(`Creating dummy SceneModelEntity "${entityId}" for unused SceneMeshes: [${unusedMeshIds.join(",")}]`)
|
|
3584
3622
|
this.createEntity({
|
|
3585
3623
|
id: entityId,
|
|
@@ -3951,6 +3989,7 @@ export class SceneModel extends Component {
|
|
|
3951
3989
|
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
3952
3990
|
this._entityList[i]._destroy();
|
|
3953
3991
|
}
|
|
3992
|
+
this._layersToFinalize = {};
|
|
3954
3993
|
// Object.entries(this._geometries).forEach(([id, geometry]) => {
|
|
3955
3994
|
// geometry.destroy();
|
|
3956
3995
|
// });
|