@xeokit/xeokit-sdk 2.6.85-renderers-refactor-v2 → 2.6.86

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.
Files changed (184) hide show
  1. package/dist/xeokit-sdk.cjs.js +44618 -13007
  2. package/dist/xeokit-sdk.es.js +44617 -13008
  3. package/dist/xeokit-sdk.es5.js +3488 -1387
  4. package/dist/xeokit-sdk.min.cjs.js +8 -8
  5. package/dist/xeokit-sdk.min.es.js +8 -8
  6. package/dist/xeokit-sdk.min.es5.js +7 -7
  7. package/package.json +1 -1
  8. package/src/plugins/lib/html/MenuEvent.js +2 -2
  9. package/src/viewer/Viewer.js +103 -55
  10. package/src/viewer/scene/canvas/Canvas.js +43 -3
  11. package/src/viewer/scene/geometry/ReadableGeometry.js +25 -0
  12. package/src/viewer/scene/lights/CubeTexture.js +13 -0
  13. package/src/viewer/scene/lights/DirLight.js +1 -2
  14. package/src/viewer/scene/lights/PointLight.js +1 -2
  15. package/src/viewer/scene/materials/Texture.js +9 -0
  16. package/src/viewer/scene/math/rtcCoords.js +38 -1
  17. package/src/viewer/scene/mesh/Mesh.js +212 -454
  18. package/src/viewer/scene/mesh/draw/DrawRenderer.js +998 -0
  19. package/src/viewer/scene/mesh/draw/DrawShaderSource.js +1504 -305
  20. package/src/viewer/scene/mesh/emphasis/EmphasisEdgesRenderer.js +259 -0
  21. package/src/viewer/scene/mesh/emphasis/EmphasisEdgesShaderSource.js +160 -0
  22. package/src/viewer/scene/mesh/emphasis/EmphasisFillRenderer.js +286 -0
  23. package/src/viewer/scene/mesh/emphasis/EmphasisFillShaderSource.js +263 -0
  24. package/src/viewer/scene/mesh/occlusion/OcclusionRenderer.js +221 -0
  25. package/src/viewer/scene/mesh/occlusion/OcclusionShaderSource.js +158 -9
  26. package/src/viewer/scene/mesh/pick/PickMeshRenderer.js +223 -0
  27. package/src/viewer/scene/mesh/pick/PickMeshShaderSource.js +151 -21
  28. package/src/viewer/scene/mesh/pick/PickTriangleRenderer.js +200 -0
  29. package/src/viewer/scene/mesh/pick/PickTriangleShaderSource.js +124 -12
  30. package/src/viewer/scene/mesh/shadow/ShadowRenderer.js +214 -0
  31. package/src/viewer/scene/mesh/shadow/ShadowShaderSource.js +97 -22
  32. package/src/viewer/scene/model/RENDER_PASSES.js +34 -0
  33. package/src/viewer/scene/model/SceneModel.js +861 -245
  34. package/src/viewer/scene/model/SceneModelEntity.js +4 -4
  35. package/src/viewer/scene/model/SceneModelMesh.js +3 -3
  36. package/src/viewer/scene/model/dtx/BindableDataTexture.js +31 -0
  37. package/src/viewer/scene/model/dtx/lines/DTXLinesBuffer.js +27 -0
  38. package/src/viewer/scene/model/dtx/lines/DTXLinesLayer.js +897 -0
  39. package/src/viewer/scene/model/dtx/lines/DTXLinesState.js +46 -0
  40. package/src/viewer/scene/model/dtx/lines/DTXLinesTextureFactory.js +411 -0
  41. package/src/viewer/scene/model/dtx/lines/dataTextureRamStats.js +49 -0
  42. package/src/viewer/scene/model/dtx/lines/rebucketPositions.js +208 -0
  43. package/src/viewer/scene/model/dtx/lines/renderers/DTXLinesColorRenderer.js +389 -0
  44. package/src/viewer/scene/model/dtx/lines/renderers/DTXLinesRenderers.js +65 -0
  45. package/src/viewer/scene/model/dtx/triangles/DTXTrianglesLayer.js +1399 -0
  46. package/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesBuffer.js +46 -0
  47. package/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesState.js +250 -0
  48. package/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesTextureFactory.js +518 -0
  49. package/src/viewer/scene/model/dtx/triangles/lib/dataTextureRamStats.js +54 -0
  50. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesColorRenderer.js +639 -0
  51. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesDepthRenderer.js +464 -0
  52. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesEdgesColorRenderer.js +423 -0
  53. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesEdgesRenderer.js +431 -0
  54. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesNormalsRenderer.js +345 -0
  55. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesOcclusionRenderer.js +436 -0
  56. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickDepthRenderer.js +466 -0
  57. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickMeshRenderer.js +437 -0
  58. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickNormalsFlatRenderer.js +460 -0
  59. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickNormalsRenderer.js +437 -0
  60. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesRenderers.js +307 -0
  61. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSilhouetteRenderer.js +472 -0
  62. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapInitRenderer.js +474 -0
  63. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapRenderer.js +435 -0
  64. package/src/viewer/scene/model/vbo/ScratchMemory.js +63 -0
  65. package/src/viewer/scene/model/vbo/VBORenderer.js +664 -0
  66. package/src/viewer/scene/model/vbo/batching/lines/VBOBatchingLinesLayer.js +704 -0
  67. package/src/viewer/scene/model/vbo/batching/lines/lib/VBOBatchingLinesBuffer.js +19 -0
  68. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLineSnapInitRenderer.js +318 -0
  69. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesColorRenderer.js +114 -0
  70. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesRenderers.js +99 -0
  71. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSilhouetteRenderer.js +124 -0
  72. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapInitRenderer.js +313 -0
  73. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapRenderer.js +311 -0
  74. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOSceneModelLineBatchingRenderer.js +24 -0
  75. package/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsLayer.js +688 -0
  76. package/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsRenderer.js +24 -0
  77. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsColorRenderer.js +168 -0
  78. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsOcclusionRenderer.js +136 -0
  79. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsPickDepthRenderer.js +156 -0
  80. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsPickMeshRenderer.js +148 -0
  81. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsRenderers.js +144 -0
  82. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsShadowRenderer.js +107 -0
  83. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSilhouetteRenderer.js +146 -0
  84. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSnapInitRenderer.js +315 -0
  85. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSnapRenderer.js +305 -0
  86. package/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesBuffer.js +24 -0
  87. package/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesLayer.js +1346 -0
  88. package/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesColorRenderer.js +131 -0
  89. package/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesEmphasisRenderer.js +135 -0
  90. package/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesRenderer.js +12 -0
  91. package/src/viewer/scene/model/vbo/batching/triangles/renderers/Renderers.js +403 -0
  92. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesBatchingRenderer.js +35 -0
  93. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorRenderer.js +252 -0
  94. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorTextureRenderer.js +294 -0
  95. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesDepthRenderer.js +115 -0
  96. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesFlatColorRenderer.js +246 -0
  97. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesNormalsRenderer.js +139 -0
  98. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesOcclusionRenderer.js +125 -0
  99. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPBRRenderer.js +561 -0
  100. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickDepthRenderer.js +144 -0
  101. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickMeshRenderer.js +130 -0
  102. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickNormalsFlatRenderer.js +121 -0
  103. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickNormalsRenderer.js +131 -0
  104. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesShadowRenderer.js +107 -0
  105. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSilhouetteRenderer.js +144 -0
  106. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapInitRenderer.js +313 -0
  107. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapRenderer.js +312 -0
  108. package/src/viewer/scene/model/vbo/float16.js +760 -0
  109. package/src/viewer/scene/model/vbo/instancing/lines/VBOInstancingLinesLayer.js +711 -0
  110. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesColorRenderer.js +148 -0
  111. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesRenderer.js +26 -0
  112. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesRenderers.js +139 -0
  113. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSilhouetteRenderer.js +127 -0
  114. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapInitRenderer.js +308 -0
  115. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapRenderer.js +299 -0
  116. package/src/viewer/scene/model/vbo/instancing/points/VBOInstancingPointsLayer.js +733 -0
  117. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsColorRenderer.js +174 -0
  118. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsDepthRenderer.js +156 -0
  119. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsOcclusionRenderer.js +149 -0
  120. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsPickDepthRenderer.js +170 -0
  121. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsPickMeshRenderer.js +152 -0
  122. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsRenderer.js +26 -0
  123. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsRenderers.js +174 -0
  124. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsShadowRenderer.js +119 -0
  125. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSilhouetteRenderer.js +154 -0
  126. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSnapInitRenderer.js +307 -0
  127. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSnapRenderer.js +293 -0
  128. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingTrianglesRenderer.js +150 -0
  129. package/src/viewer/scene/model/vbo/instancing/triangles/VBOInstancingTrianglesLayer.js +1289 -0
  130. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesColorRenderer.js +135 -0
  131. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesEmphasisRenderer.js +137 -0
  132. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesRenderer.js +12 -0
  133. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/Renderers.js +403 -0
  134. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorRenderer.js +267 -0
  135. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorTextureRenderer.js +299 -0
  136. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesDepthRenderer.js +126 -0
  137. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesFlatColorRenderer.js +255 -0
  138. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesFlatNormalsRenderer.js +130 -0
  139. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesInstancingRenderer.js +32 -0
  140. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesNormalsRenderer.js +138 -0
  141. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesOcclusionRenderer.js +128 -0
  142. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPBRRenderer.js +561 -0
  143. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickDepthRenderer.js +149 -0
  144. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickMeshRenderer.js +136 -0
  145. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickNormalsFlatRenderer.js +130 -0
  146. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickNormalsRenderer.js +145 -0
  147. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesShadowRenderer.js +113 -0
  148. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSilhouetteRenderer.js +148 -0
  149. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapInitRenderer.js +319 -0
  150. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapRenderer.js +310 -0
  151. package/src/viewer/scene/scene/Scene.js +38 -21
  152. package/src/viewer/scene/webgl/ArrayBuf.js +20 -5
  153. package/src/viewer/scene/webgl/Attribute.js +23 -0
  154. package/src/viewer/scene/webgl/FrameContext.js +86 -14
  155. package/src/viewer/scene/webgl/Program.js +181 -0
  156. package/src/viewer/scene/webgl/RenderBuffer.js +262 -62
  157. package/src/viewer/scene/webgl/RenderBufferManager.js +34 -0
  158. package/src/viewer/scene/webgl/Renderer.js +843 -880
  159. package/src/viewer/scene/webgl/Sampler.js +18 -0
  160. package/src/viewer/scene/webgl/Shader.js +49 -0
  161. package/src/viewer/scene/webgl/occlusion/OcclusionLayer.js +132 -60
  162. package/src/viewer/scene/webgl/occlusion/OcclusionTester.js +328 -167
  163. package/src/viewer/scene/webgl/sao/SAODepthLimitedBlurRenderer.js +324 -0
  164. package/src/viewer/scene/webgl/sao/SAOOcclusionRenderer.js +384 -0
  165. package/src/viewer/utils/os.js +9 -0
  166. package/src/viewer/scene/mesh/draw/LambertShaderSource.js +0 -35
  167. package/src/viewer/scene/mesh/emphasis/EmphasisShaderSource.js +0 -34
  168. package/src/viewer/scene/model/layer/DTXLayer.js +0 -940
  169. package/src/viewer/scene/model/layer/Layer.js +0 -786
  170. package/src/viewer/scene/model/layer/VBOLayer.js +0 -1019
  171. package/src/viewer/scene/model/layer/programs/ColorProgram.js +0 -35
  172. package/src/viewer/scene/model/layer/programs/ColorTextureProgram.js +0 -46
  173. package/src/viewer/scene/model/layer/programs/DepthProgram.js +0 -11
  174. package/src/viewer/scene/model/layer/programs/EdgesProgram.js +0 -12
  175. package/src/viewer/scene/model/layer/programs/FlatColorProgram.js +0 -24
  176. package/src/viewer/scene/model/layer/programs/OcclusionProgram.js +0 -12
  177. package/src/viewer/scene/model/layer/programs/PBRProgram.js +0 -180
  178. package/src/viewer/scene/model/layer/programs/PickDepthProgram.js +0 -30
  179. package/src/viewer/scene/model/layer/programs/PickMeshProgram.js +0 -12
  180. package/src/viewer/scene/model/layer/programs/PickNormalsProgram.js +0 -18
  181. package/src/viewer/scene/model/layer/programs/ShadowProgram.js +0 -23
  182. package/src/viewer/scene/model/layer/programs/SilhouetteProgram.js +0 -15
  183. package/src/viewer/scene/model/layer/programs/SnapProgram.js +0 -28
  184. package/src/viewer/scene/webgl/WebGLRenderer.js +0 -612
@@ -0,0 +1,1289 @@
1
+ import {ENTITY_FLAGS} from '../../../ENTITY_FLAGS.js';
2
+ import {RENDER_PASSES} from '../../../RENDER_PASSES.js';
3
+
4
+ import {math} from "../../../../math/math.js";
5
+ import {RenderState} from "../../../../webgl/RenderState.js";
6
+ import {ArrayBuf} from "../../../../webgl/ArrayBuf.js";
7
+ import {getRenderers} from "./renderers/Renderers.js";
8
+
9
+ const tempUint8Vec4 = new Uint8Array(4);
10
+ const tempFloat32 = new Float32Array(1);
11
+ const tempVec4a = math.vec4([0, 0, 0, 1]);
12
+ const tempVec3fa = new Float32Array(3);
13
+
14
+ const tempVec3a = math.vec3();
15
+ const tempVec3b = math.vec3();
16
+ const tempVec3c = math.vec3();
17
+ const tempVec3d = math.vec3();
18
+ const tempVec3e = math.vec3();
19
+ const tempVec3f = math.vec3();
20
+ const tempVec3g = math.vec3();
21
+
22
+ const tempFloat32Vec4 = new Float32Array(4);
23
+
24
+ /**
25
+ * @private
26
+ */
27
+ export class VBOInstancingTrianglesLayer {
28
+
29
+ /**
30
+ * @param cfg
31
+ * @param cfg.layerIndex
32
+ * @param cfg.model
33
+ * @param cfg.geometry
34
+ * @param cfg.textureSet
35
+ * @param cfg.origin
36
+ */
37
+ constructor(cfg) {
38
+
39
+ // console.info("Creating VBOInstancingTrianglesLayer");
40
+
41
+ /**
42
+ * Owner model
43
+ * @type {VBOSceneModel}
44
+ */
45
+ this.model = cfg.model;
46
+
47
+ /**
48
+ * State sorting key.
49
+ * @type {string}
50
+ */
51
+ this.sortId = "TrianglesInstancingLayer" + (cfg.solid ? "-solid" : "-surface") + (cfg.normals ? "-normals" : "-autoNormals");
52
+
53
+ /**
54
+ * Index of this InstancingLayer in VBOSceneModel#_layerList
55
+ * @type {Number}
56
+ */
57
+ this.layerIndex = cfg.layerIndex;
58
+
59
+ this._renderers = getRenderers(cfg.model.scene);
60
+
61
+ this._aabb = math.collapseAABB3();
62
+
63
+ this._state = new RenderState({
64
+ numInstances: 0,
65
+ obb: math.OBB3(),
66
+ origin: math.vec3(),
67
+ geometry: cfg.geometry,
68
+ textureSet: cfg.textureSet,
69
+ pbrSupported: false, // Set in #finalize if we have enough to support quality rendering
70
+ positionsDecodeMatrix: cfg.geometry.positionsDecodeMatrix, // So we can null the geometry for GC
71
+ colorsBuf: null,
72
+ metallicRoughnessBuf: null,
73
+ flagsBuf: null,
74
+ offsetsBuf: null,
75
+ modelMatrixBuf: null,
76
+ modelMatrixCol0Buf: null,
77
+ modelMatrixCol1Buf: null,
78
+ modelMatrixCol2Buf: null,
79
+ modelNormalMatrixCol0Buf: null,
80
+ modelNormalMatrixCol1Buf: null,
81
+ modelNormalMatrixCol2Buf: null,
82
+ pickColorsBuf: null
83
+ });
84
+
85
+ // These counts are used to avoid unnecessary render passes
86
+ this._numPortions = 0;
87
+ this._numVisibleLayerPortions = 0;
88
+ this._numTransparentLayerPortions = 0;
89
+ this._numXRayedLayerPortions = 0;
90
+ this._numHighlightedLayerPortions = 0;
91
+ this._numSelectedLayerPortions = 0;
92
+ this._numClippableLayerPortions = 0;
93
+ this._numEdgesLayerPortions = 0;
94
+ this._numPickableLayerPortions = 0;
95
+ this._numCulledLayerPortions = 0;
96
+
97
+ /** @private */
98
+ this.numIndices = cfg.geometry.numIndices;
99
+
100
+ // Vertex arrays
101
+ this._colors = [];
102
+ this._metallicRoughness = [];
103
+ this._pickColors = [];
104
+ this._offsets = [];
105
+
106
+ // Modeling matrix per instance, array for each column
107
+
108
+ this._modelMatrix = [];
109
+
110
+ this._modelMatrixCol0 = [];
111
+ this._modelMatrixCol1 = [];
112
+ this._modelMatrixCol2 = [];
113
+
114
+ // Modeling normal matrix per instance, array for each column
115
+ this._modelNormalMatrixCol0 = [];
116
+ this._modelNormalMatrixCol1 = [];
117
+ this._modelNormalMatrixCol2 = [];
118
+
119
+ this._portions = [];
120
+ this._meshes = [];
121
+
122
+ this._aabb = math.collapseAABB3();
123
+ this.aabbDirty = true;
124
+
125
+ if (cfg.origin) {
126
+ this._state.origin.set(cfg.origin);
127
+ }
128
+
129
+ this._finalized = false;
130
+
131
+ /**
132
+ * When true, this layer contains solid triangle meshes, otherwise this layer contains surface triangle meshes
133
+ * @type {boolean}
134
+ */
135
+ this.solid = !!cfg.solid;
136
+
137
+ /**
138
+ * The number of indices in this layer.
139
+ * @type {number|*}
140
+ */
141
+ this.numIndices = cfg.geometry.numIndices;
142
+
143
+ /**
144
+ * The type of primitives in this layer.
145
+ */
146
+ this.primitive = cfg.geometry.primitive;
147
+ }
148
+
149
+ get aabb() {
150
+ if (this.aabbDirty) {
151
+ math.collapseAABB3(this._aabb);
152
+ for (let i = 0, len = this._meshes.length; i < len; i++) {
153
+ math.expandAABB3(this._aabb, this._meshes[i].aabb);
154
+ }
155
+ this.aabbDirty = false;
156
+ }
157
+ return this._aabb;
158
+ }
159
+
160
+ /**
161
+ * Creates a new portion within this InstancingLayer, returns the new portion ID.
162
+ *
163
+ * The portion will instance this InstancingLayer's geometry.
164
+ *
165
+ * Gives the portion the specified color and matrix.
166
+ *
167
+ * @param mesh The SceneModelMesh that owns the portion
168
+ * @param cfg Portion params
169
+ * @param cfg.color Color [0..255,0..255,0..255]
170
+ * @param cfg.metallic Metalness factor [0..255]
171
+ * @param cfg.roughness Roughness factor [0..255]
172
+ * @param cfg.opacity Opacity [0..255].
173
+ * @param cfg.meshMatrix Flat float 4x4 matrix.
174
+ * @param [cfg.worldMatrix] Flat float 4x4 matrix.
175
+ * @param cfg.pickColor Quantized pick color
176
+ * @returns {number} Portion ID.
177
+ */
178
+ createPortion(mesh, cfg) {
179
+
180
+ const color = cfg.color;
181
+ const metallic = cfg.metallic;
182
+ const roughness = cfg.roughness;
183
+ const opacity = cfg.opacity !== null && cfg.opacity !== undefined ? cfg.opacity : 255;
184
+ const meshMatrix = cfg.meshMatrix;
185
+ const pickColor = cfg.pickColor;
186
+
187
+ if (this._finalized) {
188
+ throw "Already finalized";
189
+ }
190
+
191
+ const r = color[0]; // Color is pre-quantized by SceneModel
192
+ const g = color[1];
193
+ const b = color[2];
194
+
195
+ this._colors.push(r);
196
+ this._colors.push(g);
197
+ this._colors.push(b);
198
+ this._colors.push(opacity);
199
+
200
+ this._metallicRoughness.push((metallic !== null && metallic !== undefined) ? metallic : 0);
201
+ this._metallicRoughness.push((roughness !== null && roughness !== undefined) ? roughness : 255);
202
+
203
+ if (this.model.scene.entityOffsetsEnabled) {
204
+ this._offsets.push(0);
205
+ this._offsets.push(0);
206
+ this._offsets.push(0);
207
+ }
208
+
209
+ this._modelMatrixCol0.push(meshMatrix[0]);
210
+ this._modelMatrixCol0.push(meshMatrix[4]);
211
+ this._modelMatrixCol0.push(meshMatrix[8]);
212
+ this._modelMatrixCol0.push(meshMatrix[12]);
213
+
214
+ this._modelMatrixCol1.push(meshMatrix[1]);
215
+ this._modelMatrixCol1.push(meshMatrix[5]);
216
+ this._modelMatrixCol1.push(meshMatrix[9]);
217
+ this._modelMatrixCol1.push(meshMatrix[13]);
218
+
219
+ this._modelMatrixCol2.push(meshMatrix[2]);
220
+ this._modelMatrixCol2.push(meshMatrix[6]);
221
+ this._modelMatrixCol2.push(meshMatrix[10]);
222
+ this._modelMatrixCol2.push(meshMatrix[14]);
223
+
224
+ if (this._state.geometry.normals) {
225
+
226
+ // Note: order of inverse and transpose doesn't matter
227
+
228
+ let transposedMat = math.transposeMat4(meshMatrix, math.mat4()); // TODO: Use cached matrix
229
+ let normalMatrix = math.inverseMat4(transposedMat);
230
+
231
+ this._modelNormalMatrixCol0.push(normalMatrix[0]);
232
+ this._modelNormalMatrixCol0.push(normalMatrix[4]);
233
+ this._modelNormalMatrixCol0.push(normalMatrix[8]);
234
+ this._modelNormalMatrixCol0.push(normalMatrix[12]);
235
+
236
+ this._modelNormalMatrixCol1.push(normalMatrix[1]);
237
+ this._modelNormalMatrixCol1.push(normalMatrix[5]);
238
+ this._modelNormalMatrixCol1.push(normalMatrix[9]);
239
+ this._modelNormalMatrixCol1.push(normalMatrix[13]);
240
+
241
+ this._modelNormalMatrixCol2.push(normalMatrix[2]);
242
+ this._modelNormalMatrixCol2.push(normalMatrix[6]);
243
+ this._modelNormalMatrixCol2.push(normalMatrix[10]);
244
+ this._modelNormalMatrixCol2.push(normalMatrix[14]);
245
+ }
246
+
247
+ // Per-vertex pick colors
248
+
249
+ this._pickColors.push(pickColor[0]);
250
+ this._pickColors.push(pickColor[1]);
251
+ this._pickColors.push(pickColor[2]);
252
+ this._pickColors.push(pickColor[3]);
253
+
254
+ this._state.numInstances++;
255
+
256
+ const portionId = this._portions.length;
257
+
258
+ const portion = {};
259
+
260
+ if (this.model.scene.readableGeometryEnabled) {
261
+ portion.matrix = meshMatrix.slice();
262
+ portion.inverseMatrix = null; // Lazy-computed in precisionRayPickSurface
263
+ portion.normalMatrix = null; // Lazy-computed in precisionRayPickSurface
264
+ }
265
+
266
+ this._portions.push(portion);
267
+
268
+ this._numPortions++;
269
+ this.model.numPortions++;
270
+ this._meshes.push(mesh);
271
+ return portionId;
272
+ }
273
+
274
+ finalize() {
275
+
276
+ if (this._finalized) {
277
+ return;
278
+ }
279
+
280
+ const state = this._state;
281
+ const geometry = state.geometry;
282
+ const textureSet = state.textureSet;
283
+ const gl = this.model.scene.canvas.gl;
284
+ const colorsLength = this._colors.length;
285
+ const flagsLength = colorsLength / 4;
286
+
287
+ if (colorsLength > 0) {
288
+ let notNormalized = false;
289
+ state.colorsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Uint8Array(this._colors), this._colors.length, 4, gl.DYNAMIC_DRAW, notNormalized);
290
+ this._colors = []; // Release memory
291
+ }
292
+
293
+ if (this._metallicRoughness.length > 0) {
294
+ const metallicRoughness = new Uint8Array(this._metallicRoughness);
295
+ let normalized = false;
296
+ state.metallicRoughnessBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, metallicRoughness, this._metallicRoughness.length, 2, gl.STATIC_DRAW, normalized);
297
+ }
298
+
299
+ if (flagsLength > 0) {
300
+ // Because we only build flags arrays here,
301
+ // get their length from the colors array
302
+ let notNormalized = false;
303
+ state.flagsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(flagsLength), flagsLength, 1, gl.DYNAMIC_DRAW, notNormalized);
304
+ }
305
+
306
+ if (this.model.scene.entityOffsetsEnabled) {
307
+ if (this._offsets.length > 0) {
308
+ const notNormalized = false;
309
+ state.offsetsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._offsets), this._offsets.length, 3, gl.DYNAMIC_DRAW, notNormalized);
310
+ this._offsets = []; // Release memory
311
+ }
312
+ }
313
+
314
+ if (geometry.positionsCompressed && geometry.positionsCompressed.length > 0) {
315
+ const normalized = false;
316
+ state.positionsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, geometry.positionsCompressed, geometry.positionsCompressed.length, 3, gl.STATIC_DRAW, normalized);
317
+ state.positionsDecodeMatrix = math.mat4(geometry.positionsDecodeMatrix);
318
+ }
319
+ // if (geometry.normalsCompressed && geometry.normalsCompressed.length > 0) {
320
+ // const normalized = true; // For oct-encoded UInt8
321
+ // state.normalsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, geometry.normalsCompressed, geometry.normalsCompressed.length, 3, gl.STATIC_DRAW, normalized);
322
+ // }
323
+ if (geometry.colorsCompressed && geometry.colorsCompressed.length > 0) {
324
+ const colorsCompressed = new Uint8Array(geometry.colorsCompressed);
325
+ const notNormalized = false;
326
+ state.colorsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, colorsCompressed, colorsCompressed.length, 4, gl.STATIC_DRAW, notNormalized);
327
+ }
328
+ if (geometry.uvCompressed && geometry.uvCompressed.length > 0) {
329
+ const uvCompressed = geometry.uvCompressed;
330
+ state.uvDecodeMatrix = geometry.uvDecodeMatrix;
331
+ state.uvBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, uvCompressed, uvCompressed.length, 2, gl.STATIC_DRAW, false);
332
+ }
333
+ if (geometry.indices && geometry.indices.length > 0) {
334
+ state.indicesBuf = new ArrayBuf(gl, gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(geometry.indices), geometry.indices.length, 1, gl.STATIC_DRAW);
335
+ state.numIndices = geometry.indices.length;
336
+ }
337
+ if (geometry.edgeIndices && geometry.edgeIndices.length > 0) {
338
+ state.edgeIndicesBuf = new ArrayBuf(gl, gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(geometry.edgeIndices), geometry.edgeIndices.length, 1, gl.STATIC_DRAW);
339
+ }
340
+
341
+ if (this._modelMatrixCol0.length > 0) {
342
+
343
+ const normalized = false;
344
+
345
+ state.modelMatrixCol0Buf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._modelMatrixCol0), this._modelMatrixCol0.length, 4, gl.STATIC_DRAW, normalized);
346
+ state.modelMatrixCol1Buf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._modelMatrixCol1), this._modelMatrixCol1.length, 4, gl.STATIC_DRAW, normalized);
347
+ state.modelMatrixCol2Buf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._modelMatrixCol2), this._modelMatrixCol2.length, 4, gl.STATIC_DRAW, normalized);
348
+ this._modelMatrixCol0 = [];
349
+ this._modelMatrixCol1 = [];
350
+ this._modelMatrixCol2 = [];
351
+
352
+ if (state.normalsBuf) {
353
+ state.modelNormalMatrixCol0Buf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._modelNormalMatrixCol0), this._modelNormalMatrixCol0.length, 4, gl.STATIC_DRAW, normalized);
354
+ state.modelNormalMatrixCol1Buf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._modelNormalMatrixCol1), this._modelNormalMatrixCol1.length, 4, gl.STATIC_DRAW, normalized);
355
+ state.modelNormalMatrixCol2Buf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._modelNormalMatrixCol2), this._modelNormalMatrixCol2.length, 4, gl.STATIC_DRAW, normalized);
356
+ this._modelNormalMatrixCol0 = [];
357
+ this._modelNormalMatrixCol1 = [];
358
+ this._modelNormalMatrixCol2 = [];
359
+ }
360
+ }
361
+
362
+ if (this._pickColors.length > 0) {
363
+ const normalized = false;
364
+ state.pickColorsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Uint8Array(this._pickColors), this._pickColors.length, 4, gl.STATIC_DRAW, normalized);
365
+ this._pickColors = []; // Release memory
366
+ }
367
+
368
+ state.pbrSupported
369
+ = !!state.metallicRoughnessBuf
370
+ && !!state.uvBuf
371
+ && !!state.normalsBuf
372
+ && !!textureSet
373
+ && !!textureSet.colorTexture
374
+ && !!textureSet.metallicRoughnessTexture;
375
+
376
+ state.colorTextureSupported
377
+ = !!state.uvBuf
378
+ && !!textureSet
379
+ && !!textureSet.colorTexture;
380
+
381
+
382
+ if (!this.model.scene.readableGeometryEnabled) {
383
+ this._state.geometry = null;
384
+ }
385
+
386
+ this._finalized = true;
387
+ }
388
+
389
+ // The following setters are called by VBOSceneModelMesh, in turn called by VBOSceneModelNode, only after the layer is finalized.
390
+ // It's important that these are called after finalize() in order to maintain integrity of counts like _numVisibleLayerPortions etc.
391
+
392
+ initFlags(portionId, flags, meshTransparent) {
393
+ if (flags & ENTITY_FLAGS.VISIBLE) {
394
+ this._numVisibleLayerPortions++;
395
+ this.model.numVisibleLayerPortions++;
396
+ }
397
+ if (flags & ENTITY_FLAGS.HIGHLIGHTED) {
398
+ this._numHighlightedLayerPortions++;
399
+ this.model.numHighlightedLayerPortions++;
400
+ }
401
+ if (flags & ENTITY_FLAGS.XRAYED) {
402
+ this._numXRayedLayerPortions++;
403
+ this.model.numXRayedLayerPortions++;
404
+ }
405
+ if (flags & ENTITY_FLAGS.SELECTED) {
406
+ this._numSelectedLayerPortions++;
407
+ this.model.numSelectedLayerPortions++;
408
+ }
409
+ if (flags & ENTITY_FLAGS.CLIPPABLE) {
410
+ this._numClippableLayerPortions++;
411
+ this.model.numClippableLayerPortions++;
412
+ }
413
+ if (flags & ENTITY_FLAGS.EDGES) {
414
+ this._numEdgesLayerPortions++;
415
+ this.model.numEdgesLayerPortions++;
416
+ }
417
+ if (flags & ENTITY_FLAGS.PICKABLE) {
418
+ this._numPickableLayerPortions++;
419
+ this.model.numPickableLayerPortions++;
420
+ }
421
+ if (flags & ENTITY_FLAGS.CULLED) {
422
+ this._numCulledLayerPortions++;
423
+ this.model.numCulledLayerPortions++;
424
+ }
425
+ if (meshTransparent) {
426
+ this._numTransparentLayerPortions++;
427
+ this.model.numTransparentLayerPortions++;
428
+ }
429
+ this._setFlags(portionId, flags, meshTransparent);
430
+ }
431
+
432
+ setVisible(portionId, flags, meshTransparent) {
433
+ if (!this._finalized) {
434
+ throw "Not finalized";
435
+ }
436
+ if (flags & ENTITY_FLAGS.VISIBLE) {
437
+ this._numVisibleLayerPortions++;
438
+ this.model.numVisibleLayerPortions++;
439
+ } else {
440
+ this._numVisibleLayerPortions--;
441
+ this.model.numVisibleLayerPortions--;
442
+ }
443
+ this._setFlags(portionId, flags, meshTransparent);
444
+ }
445
+
446
+ setHighlighted(portionId, flags, meshTransparent) {
447
+ if (!this._finalized) {
448
+ throw "Not finalized";
449
+ }
450
+ if (flags & ENTITY_FLAGS.HIGHLIGHTED) {
451
+ this._numHighlightedLayerPortions++;
452
+ this.model.numHighlightedLayerPortions++;
453
+ } else {
454
+ this._numHighlightedLayerPortions--;
455
+ this.model.numHighlightedLayerPortions--;
456
+ }
457
+ this._setFlags(portionId, flags, meshTransparent);
458
+ }
459
+
460
+ setXRayed(portionId, flags, meshTransparent) {
461
+ if (!this._finalized) {
462
+ throw "Not finalized";
463
+ }
464
+ if (flags & ENTITY_FLAGS.XRAYED) {
465
+ this._numXRayedLayerPortions++;
466
+ this.model.numXRayedLayerPortions++;
467
+ } else {
468
+ this._numXRayedLayerPortions--;
469
+ this.model.numXRayedLayerPortions--;
470
+ }
471
+ this._setFlags(portionId, flags, meshTransparent);
472
+ }
473
+
474
+ setSelected(portionId, flags, meshTransparent) {
475
+ if (!this._finalized) {
476
+ throw "Not finalized";
477
+ }
478
+ if (flags & ENTITY_FLAGS.SELECTED) {
479
+ this._numSelectedLayerPortions++;
480
+ this.model.numSelectedLayerPortions++;
481
+ } else {
482
+ this._numSelectedLayerPortions--;
483
+ this.model.numSelectedLayerPortions--;
484
+ }
485
+ this._setFlags(portionId, flags, meshTransparent);
486
+ }
487
+
488
+ setEdges(portionId, flags, meshTransparent) {
489
+ if (!this._finalized) {
490
+ throw "Not finalized";
491
+ }
492
+ if (flags & ENTITY_FLAGS.EDGES) {
493
+ this._numEdgesLayerPortions++;
494
+ this.model.numEdgesLayerPortions++;
495
+ } else {
496
+ this._numEdgesLayerPortions--;
497
+ this.model.numEdgesLayerPortions--;
498
+ }
499
+ this._setFlags(portionId, flags, meshTransparent);
500
+ }
501
+
502
+ setClippable(portionId, flags) {
503
+ if (!this._finalized) {
504
+ throw "Not finalized";
505
+ }
506
+ if (flags & ENTITY_FLAGS.CLIPPABLE) {
507
+ this._numClippableLayerPortions++;
508
+ this.model.numClippableLayerPortions++;
509
+ } else {
510
+ this._numClippableLayerPortions--;
511
+ this.model.numClippableLayerPortions--;
512
+ }
513
+ this._setFlags(portionId, flags);
514
+ }
515
+
516
+ setCollidable(portionId, flags) {
517
+ if (!this._finalized) {
518
+ throw "Not finalized";
519
+ }
520
+ }
521
+
522
+ setPickable(portionId, flags, meshTransparent) {
523
+ if (!this._finalized) {
524
+ throw "Not finalized";
525
+ }
526
+ if (flags & ENTITY_FLAGS.PICKABLE) {
527
+ this._numPickableLayerPortions++;
528
+ this.model.numPickableLayerPortions++;
529
+ } else {
530
+ this._numPickableLayerPortions--;
531
+ this.model.numPickableLayerPortions--;
532
+ }
533
+ this._setFlags(portionId, flags, meshTransparent);
534
+ }
535
+
536
+ setCulled(portionId, flags, meshTransparent) {
537
+ if (!this._finalized) {
538
+ throw "Not finalized";
539
+ }
540
+ if (flags & ENTITY_FLAGS.CULLED) {
541
+ this._numCulledLayerPortions++;
542
+ this.model.numCulledLayerPortions++;
543
+ } else {
544
+ this._numCulledLayerPortions--;
545
+ this.model.numCulledLayerPortions--;
546
+ }
547
+ this._setFlags(portionId, flags, meshTransparent);
548
+ }
549
+
550
+ setColor(portionId, color) { // RGBA color is normalized as ints
551
+ if (!this._finalized) {
552
+ throw "Not finalized";
553
+ }
554
+ tempUint8Vec4[0] = color[0];
555
+ tempUint8Vec4[1] = color[1];
556
+ tempUint8Vec4[2] = color[2];
557
+ tempUint8Vec4[3] = color[3];
558
+ if (this._state.colorsBuf) {
559
+ this._state.colorsBuf.setData(tempUint8Vec4, portionId * 4);
560
+ }
561
+ }
562
+
563
+ setTransparent(portionId, flags, transparent) {
564
+ if (transparent) {
565
+ this._numTransparentLayerPortions++;
566
+ this.model.numTransparentLayerPortions++;
567
+ } else {
568
+ this._numTransparentLayerPortions--;
569
+ this.model.numTransparentLayerPortions--;
570
+ }
571
+ this._setFlags(portionId, flags, transparent);
572
+ }
573
+
574
+ // setMatrix(portionId, matrix) {
575
+ //
576
+ // if (!this._finalized) {
577
+ // throw "Not finalized";
578
+ // }
579
+ //
580
+ // var offset = portionId * 4;
581
+ //
582
+ // tempFloat32Vec4[0] = matrix[0];
583
+ // tempFloat32Vec4[1] = matrix[4];
584
+ // tempFloat32Vec4[2] = matrix[8];
585
+ // tempFloat32Vec4[3] = matrix[12];
586
+ //
587
+ // this._state.modelMatrixCol0Buf.setData(tempFloat32Vec4, offset);
588
+ //
589
+ // tempFloat32Vec4[0] = matrix[1];
590
+ // tempFloat32Vec4[1] = matrix[5];
591
+ // tempFloat32Vec4[2] = matrix[9];
592
+ // tempFloat32Vec4[3] = matrix[13];
593
+ //
594
+ // this._state.modelMatrixCol1Buf.setData(tempFloat32Vec4, offset);
595
+ //
596
+ // tempFloat32Vec4[0] = matrix[2];
597
+ // tempFloat32Vec4[1] = matrix[6];
598
+ // tempFloat32Vec4[2] = matrix[10];
599
+ // tempFloat32Vec4[3] = matrix[14];
600
+ //
601
+ // this._state.modelMatrixCol2Buf.setData(tempFloat32Vec4, offset);
602
+ // }
603
+
604
+ /**
605
+ * flags are 4bits values encoded on a 32bit base. color flag on the first 4 bits, silhouette flag on the next 4 bits and so on for edge, pick and clippable.
606
+ */
607
+ _setFlags(portionId, flags, meshTransparent) {
608
+
609
+ if (!this._finalized) {
610
+ throw "Not finalized";
611
+ }
612
+
613
+ const visible = !!(flags & ENTITY_FLAGS.VISIBLE);
614
+ const xrayed = !!(flags & ENTITY_FLAGS.XRAYED);
615
+ const highlighted = !!(flags & ENTITY_FLAGS.HIGHLIGHTED);
616
+ const selected = !!(flags & ENTITY_FLAGS.SELECTED);
617
+ const edges = !!(flags & ENTITY_FLAGS.EDGES);
618
+ const pickable = !!(flags & ENTITY_FLAGS.PICKABLE);
619
+ const culled = !!(flags & ENTITY_FLAGS.CULLED);
620
+
621
+ let colorFlag;
622
+ if (!visible || culled || xrayed
623
+ || (highlighted && !this.model.scene.highlightMaterial.glowThrough)
624
+ || (selected && !this.model.scene.selectedMaterial.glowThrough)) {
625
+ colorFlag = RENDER_PASSES.NOT_RENDERED;
626
+ } else {
627
+ if (meshTransparent) {
628
+ colorFlag = RENDER_PASSES.COLOR_TRANSPARENT;
629
+ } else {
630
+ colorFlag = RENDER_PASSES.COLOR_OPAQUE;
631
+ }
632
+ }
633
+
634
+ let silhouetteFlag;
635
+ if (!visible || culled) {
636
+ silhouetteFlag = RENDER_PASSES.NOT_RENDERED;
637
+ } else if (selected) {
638
+ silhouetteFlag = RENDER_PASSES.SILHOUETTE_SELECTED;
639
+ } else if (highlighted) {
640
+ silhouetteFlag = RENDER_PASSES.SILHOUETTE_HIGHLIGHTED;
641
+ } else if (xrayed) {
642
+ silhouetteFlag = RENDER_PASSES.SILHOUETTE_XRAYED;
643
+ } else {
644
+ silhouetteFlag = RENDER_PASSES.NOT_RENDERED;
645
+ }
646
+
647
+ let edgeFlag = 0;
648
+ if (!visible || culled) {
649
+ edgeFlag = RENDER_PASSES.NOT_RENDERED;
650
+ } else if (selected) {
651
+ edgeFlag = RENDER_PASSES.EDGES_SELECTED;
652
+ } else if (highlighted) {
653
+ edgeFlag = RENDER_PASSES.EDGES_HIGHLIGHTED;
654
+ } else if (xrayed) {
655
+ edgeFlag = RENDER_PASSES.EDGES_XRAYED;
656
+ } else if (edges) {
657
+ if (meshTransparent) {
658
+ edgeFlag = RENDER_PASSES.EDGES_COLOR_TRANSPARENT;
659
+ } else {
660
+ edgeFlag = RENDER_PASSES.EDGES_COLOR_OPAQUE;
661
+ }
662
+ } else {
663
+ edgeFlag = RENDER_PASSES.NOT_RENDERED;
664
+ }
665
+
666
+ const pickFlag = (visible && !culled && pickable) ? RENDER_PASSES.PICK : RENDER_PASSES.NOT_RENDERED;
667
+
668
+ const clippableFlag = !!(flags & ENTITY_FLAGS.CLIPPABLE) ? 1 : 0;
669
+
670
+ let vertFlag = 0;
671
+ vertFlag |= colorFlag;
672
+ vertFlag |= silhouetteFlag << 4;
673
+ vertFlag |= edgeFlag << 8;
674
+ vertFlag |= pickFlag << 12;
675
+ vertFlag |= clippableFlag << 16;
676
+
677
+ tempFloat32[0] = vertFlag;
678
+
679
+ if (this._state.flagsBuf) {
680
+ this._state.flagsBuf.setData(tempFloat32, portionId);
681
+ }
682
+ }
683
+
684
+ setOffset(portionId, offset) {
685
+ if (!this._finalized) {
686
+ throw "Not finalized";
687
+ }
688
+ if (!this.model.scene.entityOffsetsEnabled) {
689
+ this.model.error("Entity#offset not enabled for this Viewer"); // See Viewer entityOffsetsEnabled
690
+ return;
691
+ }
692
+ tempVec3fa[0] = offset[0];
693
+ tempVec3fa[1] = offset[1];
694
+ tempVec3fa[2] = offset[2];
695
+ if (this._state.offsetsBuf) {
696
+ this._state.offsetsBuf.setData(tempVec3fa, portionId * 3);
697
+ }
698
+ }
699
+
700
+ getEachVertex(portionId, callback) {
701
+ if (!this.model.scene.readableGeometryEnabled) {
702
+ return false;
703
+ }
704
+ const state = this._state;
705
+ const geometry = state.geometry;
706
+ const portion = this._portions[portionId];
707
+ if (!portion) {
708
+ this.model.error("portion not found: " + portionId);
709
+ return;
710
+ }
711
+ const positions = geometry.positionsCompressed;
712
+ const sceneModelMatrix = this.model.matrix;
713
+ const origin = math.vec4();
714
+ origin.set(state.origin, 0);
715
+ origin[3] = 1;
716
+ math.mulMat4v4(sceneModelMatrix, origin, origin);
717
+ const offsetX = origin[0];
718
+ const offsetY = origin[1];
719
+ const offsetZ = origin[2];
720
+ const worldPos = tempVec4a;
721
+ const portionMatrix = portion.matrix;
722
+ const positionsDecodeMatrix = state.positionsDecodeMatrix;
723
+ for (let i = 0, len = positions.length; i < len; i += 3) {
724
+ worldPos[0] = positions[i];
725
+ worldPos[1] = positions[i + 1];
726
+ worldPos[2] = positions[i + 2];
727
+ math.decompressPosition(worldPos, positionsDecodeMatrix);
728
+ math.transformPoint3(portionMatrix, worldPos, worldPos);
729
+ worldPos[3] = 1;
730
+ math.mulMat4v4(sceneModelMatrix, worldPos, worldPos);
731
+ worldPos[0] += offsetX;
732
+ worldPos[1] += offsetY;
733
+ worldPos[2] += offsetZ;
734
+ callback(worldPos);
735
+ }
736
+ }
737
+
738
+ getEachIndex(portionId, callback) {
739
+ if (!this.model.scene.readableGeometryEnabled) {
740
+ return false;
741
+ }
742
+ const state = this._state;
743
+ const geometry = state.geometry;
744
+ const portion = this._portions[portionId];
745
+ if (!portion) {
746
+ this.model.error("portion not found: " + portionId);
747
+ return;
748
+ }
749
+ const indices = geometry.indices;
750
+ for (let i = 0, len = indices.length; i < len; i++) {
751
+ callback(indices[i]);
752
+ }
753
+ }
754
+
755
+ setMatrix(portionId, matrix) {
756
+ if (!this._finalized) {
757
+ throw "Not finalized";
758
+ }
759
+
760
+ ////////////////////////////////////////
761
+ // TODO: Update portion matrix
762
+ ////////////////////////////////////////
763
+
764
+ var offset = portionId * 4;
765
+
766
+ tempFloat32Vec4[0] = matrix[0];
767
+ tempFloat32Vec4[1] = matrix[4];
768
+ tempFloat32Vec4[2] = matrix[8];
769
+ tempFloat32Vec4[3] = matrix[12];
770
+
771
+ this._state.modelMatrixCol0Buf.setData(tempFloat32Vec4, offset);
772
+
773
+ tempFloat32Vec4[0] = matrix[1];
774
+ tempFloat32Vec4[1] = matrix[5];
775
+ tempFloat32Vec4[2] = matrix[9];
776
+ tempFloat32Vec4[3] = matrix[13];
777
+
778
+ this._state.modelMatrixCol1Buf.setData(tempFloat32Vec4, offset);
779
+
780
+ tempFloat32Vec4[0] = matrix[2];
781
+ tempFloat32Vec4[1] = matrix[6];
782
+ tempFloat32Vec4[2] = matrix[10];
783
+ tempFloat32Vec4[3] = matrix[14];
784
+
785
+ this._state.modelMatrixCol2Buf.setData(tempFloat32Vec4, offset);
786
+ }
787
+
788
+ readGeometryData(portionId) {
789
+ if (!this._finalized) {
790
+ throw "Not finalized";
791
+ }
792
+
793
+ const state = this._state;
794
+ const sceneModelMatrix = this.model.matrix;
795
+
796
+ const col0 = state.modelMatrixCol0Buf.getData(portionId, 1);
797
+ const col1 = state.modelMatrixCol1Buf.getData(portionId, 1);
798
+ const col2 = state.modelMatrixCol2Buf.getData(portionId, 1);
799
+
800
+ const portionMatrix = [
801
+ col0[0], col1[0], col2[0], 0,
802
+ col0[1], col1[1], col2[1], 0,
803
+ col0[2], col1[2], col2[2], 0,
804
+ col0[3], col1[3], col2[3], 1,
805
+ ];
806
+
807
+ const positionsDecodeMatrix = state.positionsDecodeMatrix;
808
+
809
+ const origin = math.vec4();
810
+ origin.set(state.origin, 0);
811
+ origin[3] = 1;
812
+ math.mulMat4v4(sceneModelMatrix, origin, origin);
813
+
814
+ const indices = state.indicesBuf.getData();
815
+
816
+ const matrix = math.mulMat4(
817
+ portionMatrix,
818
+ positionsDecodeMatrix,
819
+ new Array(16)
820
+ );
821
+
822
+ math.mulMat4(
823
+ sceneModelMatrix,
824
+ matrix,
825
+ matrix
826
+ );
827
+
828
+ matrix[12] += origin[0];
829
+ matrix[13] += origin[1];
830
+ matrix[14] += origin[2];
831
+
832
+ const positionsQuantized = state.positionsBuf.getData();
833
+
834
+ const positions = math.transformPositions3(
835
+ matrix,
836
+ positionsQuantized,
837
+ new Array(positionsQuantized.length)
838
+ );
839
+
840
+ // const aabb = math.positions3ToAABB3(positions);
841
+ // console.log({aabbToniInstancing: aabb});
842
+
843
+ return { indices, positions };
844
+ }
845
+
846
+ // ---------------------- COLOR RENDERING -----------------------------------
847
+
848
+ drawColorOpaque(renderFlags, frameCtx) {
849
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0 || this._numTransparentLayerPortions === this._numPortions || this._numXRayedLayerPortions === this._numPortions) {
850
+ return;
851
+ }
852
+ this._updateBackfaceCull(renderFlags, frameCtx);
853
+ const useAlphaCutoff = this._state.textureSet && (typeof (this._state.textureSet.alphaCutoff) === "number");
854
+ if (frameCtx.withSAO && this.model.saoEnabled) {
855
+ if (frameCtx.pbrEnabled && this.model.pbrEnabled && this._state.pbrSupported) {
856
+ if (this._renderers.pbrRendererWithSAO) {
857
+ this._renderers.pbrRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
858
+ }
859
+ } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
860
+ if (useAlphaCutoff) {
861
+ if (this._renderers.colorTextureRendererWithSAOAlphaCutoff) {
862
+ this._renderers.colorTextureRendererWithSAOAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
863
+ }
864
+ } else {
865
+ if (this._renderers.colorTextureRendererWithSAO) {
866
+ this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
867
+ }
868
+ }
869
+ } else if (this._state.normalsBuf) {
870
+ if (this._renderers.colorRendererWithSAO) {
871
+ this._renderers.colorRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
872
+ }
873
+ } else {
874
+ if (this._renderers.flatColorRendererWithSAO) {
875
+ this._renderers.flatColorRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
876
+ }
877
+ }
878
+ } else if (frameCtx.pbrEnabled && this.model.pbrEnabled && this._state.pbrSupported) {
879
+ if (this._renderers.pbrRenderer) {
880
+ this._renderers.pbrRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
881
+ }
882
+ } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
883
+ if (useAlphaCutoff) {
884
+ if (this._renderers.colorTextureRendererAlphaCutoff) {
885
+ this._renderers.colorTextureRendererAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
886
+ }
887
+ } else {
888
+ if (this._renderers.colorTextureRenderer) {
889
+ this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
890
+ }
891
+ }
892
+ } else if (this._state.normalsBuf) {
893
+ if (this._renderers.colorRenderer) {
894
+ this._renderers.colorRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
895
+ }
896
+ } else {
897
+ if (this._renderers.flatColorRenderer) {
898
+ this._renderers.flatColorRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
899
+ }
900
+ }
901
+ }
902
+
903
+ _updateBackfaceCull(renderFlags, frameCtx) {
904
+ const backfaces = true; // See XCD-230
905
+ if (frameCtx.backfaces !== backfaces) {
906
+ const gl = frameCtx.gl;
907
+ if (backfaces) {
908
+ gl.disable(gl.CULL_FACE);
909
+ } else {
910
+ gl.enable(gl.CULL_FACE);
911
+ }
912
+ frameCtx.backfaces = backfaces;
913
+ }
914
+ }
915
+
916
+ drawColorTransparent(renderFlags, frameCtx) {
917
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0 || this._numTransparentLayerPortions === 0 || this._numXRayedLayerPortions === this._numPortions) {
918
+ return;
919
+ }
920
+ this._updateBackfaceCull(renderFlags, frameCtx);
921
+ if (frameCtx.pbrEnabled && this.model.pbrEnabled && this._state.pbrSupported) {
922
+ if (this._renderers.pbrRenderer) {
923
+ this._renderers.pbrRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
924
+ }
925
+ } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
926
+ if (this._renderers.colorTextureRenderer) {
927
+ this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
928
+ }
929
+ } else if (this._state.normalsBuf) {
930
+ if (this._renderers.colorRenderer) {
931
+ this._renderers.colorRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
932
+ }
933
+ } else {
934
+ if (this._renderers.flatColorRenderer) {
935
+ this._renderers.flatColorRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
936
+ }
937
+ }
938
+ }
939
+
940
+ // ---------------------- RENDERING SAO POST EFFECT TARGETS --------------
941
+
942
+ drawDepth(renderFlags, frameCtx) {
943
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0 || this._numTransparentLayerPortions === this._numPortions || this._numXRayedLayerPortions === this._numPortions) {
944
+ return;
945
+ }
946
+ this._updateBackfaceCull(renderFlags, frameCtx);
947
+ if (this._renderers.depthRenderer) {
948
+ this._renderers.depthRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE); // Assume whatever post-effect uses depth (eg SAO) does not apply to transparent objects
949
+ }
950
+ }
951
+
952
+ drawNormals(renderFlags, frameCtx) {
953
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0 || this._numTransparentLayerPortions === this._numPortions || this._numXRayedLayerPortions === this._numPortions) {
954
+ return;
955
+ }
956
+ this._updateBackfaceCull(renderFlags, frameCtx);
957
+ if (this._renderers.normalsRenderer) {
958
+ this._renderers.normalsRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE); // Assume whatever post-effect uses normals (eg SAO) does not apply to transparent objects
959
+ }
960
+ }
961
+
962
+ // ---------------------- SILHOUETTE RENDERING -----------------------------------
963
+
964
+ drawSilhouetteXRayed(renderFlags, frameCtx) {
965
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0 || this._numXRayedLayerPortions === 0) {
966
+ return;
967
+ }
968
+ this._updateBackfaceCull(renderFlags, frameCtx);
969
+ if (this._renderers.silhouetteRenderer) {
970
+ this._renderers.silhouetteRenderer.drawLayer(frameCtx, this, RENDER_PASSES.SILHOUETTE_XRAYED);
971
+ }
972
+ }
973
+
974
+ drawSilhouetteHighlighted(renderFlags, frameCtx) {
975
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0 || this._numHighlightedLayerPortions === 0) {
976
+ return;
977
+ }
978
+ this._updateBackfaceCull(renderFlags, frameCtx);
979
+ if (this._renderers.silhouetteRenderer) {
980
+ this._renderers.silhouetteRenderer.drawLayer(frameCtx, this, RENDER_PASSES.SILHOUETTE_HIGHLIGHTED);
981
+ }
982
+ }
983
+
984
+ drawSilhouetteSelected(renderFlags, frameCtx) {
985
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0 || this._numSelectedLayerPortions === 0) {
986
+ return;
987
+ }
988
+ this._updateBackfaceCull(renderFlags, frameCtx);
989
+ if (this._renderers.silhouetteRenderer) {
990
+ this._renderers.silhouetteRenderer.drawLayer(frameCtx, this, RENDER_PASSES.SILHOUETTE_SELECTED);
991
+ }
992
+ }
993
+
994
+ // ---------------------- EDGES RENDERING -----------------------------------
995
+
996
+ drawEdgesColorOpaque(renderFlags, frameCtx) {
997
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0 || this._numEdgesLayerPortions === 0) {
998
+ return;
999
+ }
1000
+ if (this._renderers.edgesColorRenderer) {
1001
+ this._renderers.edgesColorRenderer.drawLayer(frameCtx, this, RENDER_PASSES.EDGES_COLOR_OPAQUE);
1002
+ }
1003
+ }
1004
+
1005
+ drawEdgesColorTransparent(renderFlags, frameCtx) {
1006
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0 || this._numEdgesLayerPortions === 0) {
1007
+ return;
1008
+ }
1009
+ if (this._renderers.edgesColorRenderer) {
1010
+ this._renderers.edgesColorRenderer.drawLayer(frameCtx, this, RENDER_PASSES.EDGES_COLOR_TRANSPARENT);
1011
+ }
1012
+ }
1013
+
1014
+ drawEdgesXRayed(renderFlags, frameCtx) {
1015
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0 || this._numXRayedLayerPortions === 0) {
1016
+ return;
1017
+ }
1018
+ if (this._renderers.edgesRenderer) {
1019
+ this._renderers.edgesRenderer.drawLayer(frameCtx, this, RENDER_PASSES.EDGES_XRAYED);
1020
+ }
1021
+ }
1022
+
1023
+ drawEdgesHighlighted(renderFlags, frameCtx) {
1024
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0 || this._numHighlightedLayerPortions === 0) {
1025
+ return;
1026
+ }
1027
+ if (this._renderers.edgesRenderer) {
1028
+ this._renderers.edgesRenderer.drawLayer(frameCtx, this, RENDER_PASSES.EDGES_HIGHLIGHTED);
1029
+ }
1030
+ }
1031
+
1032
+ drawEdgesSelected(renderFlags, frameCtx) {
1033
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0 || this._numSelectedLayerPortions === 0) {
1034
+ return;
1035
+ }
1036
+ if (this._renderers.edgesRenderer) {
1037
+ this._renderers.edgesRenderer.drawLayer(frameCtx, this, RENDER_PASSES.EDGES_SELECTED);
1038
+ }
1039
+ }
1040
+
1041
+ // ---------------------- OCCLUSION CULL RENDERING -----------------------------------
1042
+
1043
+ drawOcclusion(renderFlags, frameCtx) {
1044
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0) {
1045
+ return;
1046
+ }
1047
+ this._updateBackfaceCull(renderFlags, frameCtx);
1048
+ if (this._renderers.occlusionRenderer) {
1049
+ // Only opaque, filled objects can be occluders
1050
+ this._renderers.occlusionRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
1051
+ }
1052
+ }
1053
+
1054
+ // ---------------------- SHADOW BUFFER RENDERING -----------------------------------
1055
+
1056
+ drawShadow(renderFlags, frameCtx) {
1057
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0) {
1058
+ return;
1059
+ }
1060
+ this._updateBackfaceCull(renderFlags, frameCtx);
1061
+ if (this._renderers.shadowRenderer) {
1062
+ this._renderers.shadowRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
1063
+ }
1064
+ }
1065
+
1066
+ //---- PICKING ----------------------------------------------------------------------------------------------------
1067
+
1068
+ drawPickMesh(renderFlags, frameCtx) {
1069
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0) {
1070
+ return;
1071
+ }
1072
+ this._updateBackfaceCull(renderFlags, frameCtx);
1073
+ if (this._renderers.pickMeshRenderer) {
1074
+ this._renderers.pickMeshRenderer.drawLayer(frameCtx, this, RENDER_PASSES.PICK);
1075
+ }
1076
+ }
1077
+
1078
+ drawPickDepths(renderFlags, frameCtx) {
1079
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0) {
1080
+ return;
1081
+ }
1082
+ this._updateBackfaceCull(renderFlags, frameCtx);
1083
+ if (this._renderers.pickDepthRenderer) {
1084
+ this._renderers.pickDepthRenderer.drawLayer(frameCtx, this, RENDER_PASSES.PICK);
1085
+ }
1086
+ }
1087
+
1088
+ drawPickNormals(renderFlags, frameCtx) {
1089
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0) {
1090
+ return;
1091
+ }
1092
+ this._updateBackfaceCull(renderFlags, frameCtx);
1093
+
1094
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
1095
+ // TODO
1096
+ // if (this._state.normalsBuf) {
1097
+ // if (this._renderers.pickNormalsRenderer) {
1098
+ // this._renderers.pickNormalsRenderer.drawLayer(frameCtx, this, RENDER_PASSES.PICK);
1099
+ // }
1100
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
1101
+ // } else {
1102
+ if (this._renderers.pickNormalsFlatRenderer) {
1103
+ this._renderers.pickNormalsFlatRenderer.drawLayer(frameCtx, this, RENDER_PASSES.PICK);
1104
+ }
1105
+ // }
1106
+ }
1107
+
1108
+ drawSnapInit(renderFlags, frameCtx) {
1109
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0) {
1110
+ return;
1111
+ }
1112
+ this._updateBackfaceCull(renderFlags, frameCtx);
1113
+ if (this._renderers.snapInitRenderer) {
1114
+ this._renderers.snapInitRenderer.drawLayer(frameCtx, this, RENDER_PASSES.PICK);
1115
+ }
1116
+ }
1117
+
1118
+ drawSnap(renderFlags, frameCtx) {
1119
+ if (this._numCulledLayerPortions === this._numPortions || this._numVisibleLayerPortions === 0) {
1120
+ return;
1121
+ }
1122
+ this._updateBackfaceCull(renderFlags, frameCtx);
1123
+ if (this._renderers.snapRenderer) {
1124
+ this._renderers.snapRenderer.drawLayer(frameCtx, this, RENDER_PASSES.PICK);
1125
+ }
1126
+ }
1127
+
1128
+ //-----------------------------------------------------------------------------------------
1129
+
1130
+ precisionRayPickSurface(portionId, worldRayOrigin, worldRayDir, worldSurfacePos, worldNormal) {
1131
+
1132
+ if (!this.model.scene.readableGeometryEnabled) {
1133
+ return false;
1134
+ }
1135
+
1136
+ const geometry = this._state.geometry;
1137
+ const state = this._state;
1138
+ const portion = this._portions[portionId];
1139
+
1140
+ if (!portion) {
1141
+ this.model.error("portion not found: " + portionId);
1142
+ return false;
1143
+ }
1144
+
1145
+ if (!portion.inverseMatrix) {
1146
+ portion.inverseMatrix = math.inverseMat4(portion.matrix, math.mat4());
1147
+ }
1148
+
1149
+ if (worldNormal && !portion.normalMatrix) {
1150
+ portion.normalMatrix = math.transposeMat4(portion.inverseMatrix, math.mat4());
1151
+ }
1152
+
1153
+ const quantizedPositions = geometry.quantizedPositions;
1154
+ const indices = geometry.indices;
1155
+ const origin = state.origin;
1156
+ const offset = portion.offset;
1157
+
1158
+ const rtcRayOrigin = tempVec3a;
1159
+ const rtcRayDir = tempVec3b;
1160
+
1161
+ rtcRayOrigin.set(origin ? math.subVec3(worldRayOrigin, origin, tempVec3c) : worldRayOrigin); // World -> RTC
1162
+ rtcRayDir.set(worldRayDir);
1163
+
1164
+ if (offset) {
1165
+ math.subVec3(rtcRayOrigin, offset);
1166
+ }
1167
+
1168
+ math.transformRay(this.model.worldNormalMatrix, rtcRayOrigin, rtcRayDir, rtcRayOrigin, rtcRayDir);
1169
+
1170
+ math.transformRay(portion.inverseMatrix, rtcRayOrigin, rtcRayDir, rtcRayOrigin, rtcRayDir);
1171
+
1172
+ const a = tempVec3d;
1173
+ const b = tempVec3e;
1174
+ const c = tempVec3f;
1175
+
1176
+ let gotIntersect = false;
1177
+ let closestDist = 0;
1178
+ const closestIntersectPos = tempVec3g;
1179
+
1180
+ for (let i = 0, len = indices.length; i < len; i += 3) {
1181
+
1182
+ const ia = indices[i + 0] * 3;
1183
+ const ib = indices[i + 1] * 3;
1184
+ const ic = indices[i + 2] * 3;
1185
+
1186
+ a[0] = quantizedPositions[ia];
1187
+ a[1] = quantizedPositions[ia + 1];
1188
+ a[2] = quantizedPositions[ia + 2];
1189
+
1190
+ b[0] = quantizedPositions[ib];
1191
+ b[1] = quantizedPositions[ib + 1];
1192
+ b[2] = quantizedPositions[ib + 2];
1193
+
1194
+ c[0] = quantizedPositions[ic];
1195
+ c[1] = quantizedPositions[ic + 1];
1196
+ c[2] = quantizedPositions[ic + 2];
1197
+
1198
+ const {positionsDecodeMatrix} = state.geometry;
1199
+
1200
+ math.decompressPosition(a, positionsDecodeMatrix);
1201
+ math.decompressPosition(b, positionsDecodeMatrix);
1202
+ math.decompressPosition(c, positionsDecodeMatrix);
1203
+
1204
+ if (math.rayTriangleIntersect(rtcRayOrigin, rtcRayDir, a, b, c, closestIntersectPos)) {
1205
+
1206
+ math.transformPoint3(portion.matrix, closestIntersectPos, closestIntersectPos);
1207
+
1208
+ math.transformPoint3(this.model.worldMatrix, closestIntersectPos, closestIntersectPos);
1209
+
1210
+ if (offset) {
1211
+ math.addVec3(closestIntersectPos, offset);
1212
+ }
1213
+
1214
+ if (origin) {
1215
+ math.addVec3(closestIntersectPos, origin);
1216
+ }
1217
+
1218
+ const dist = Math.abs(math.lenVec3(math.subVec3(closestIntersectPos, worldRayOrigin, [])));
1219
+
1220
+ if (!gotIntersect || dist > closestDist) {
1221
+ closestDist = dist;
1222
+ worldSurfacePos.set(closestIntersectPos);
1223
+ if (worldNormal) { // Not that wasteful to eagerly compute - unlikely to hit >2 surfaces on most geometry
1224
+ math.triangleNormal(a, b, c, worldNormal);
1225
+ }
1226
+ gotIntersect = true;
1227
+ }
1228
+ }
1229
+ }
1230
+
1231
+ if (gotIntersect && worldNormal) {
1232
+ math.transformVec3(portion.normalMatrix, worldNormal, worldNormal);
1233
+ math.transformVec3(this.model.worldNormalMatrix, worldNormal, worldNormal);
1234
+ math.normalizeVec3(worldNormal);
1235
+ }
1236
+
1237
+ return gotIntersect;
1238
+ }
1239
+
1240
+ destroy() {
1241
+ const state = this._state;
1242
+ if (state.colorsBuf) {
1243
+ state.colorsBuf.destroy();
1244
+ state.colorsBuf = null;
1245
+ }
1246
+ if (state.metallicRoughnessBuf) {
1247
+ state.metallicRoughnessBuf.destroy();
1248
+ state.metallicRoughnessBuf = null;
1249
+ }
1250
+ if (state.flagsBuf) {
1251
+ state.flagsBuf.destroy();
1252
+ state.flagsBuf = null;
1253
+ }
1254
+ if (state.offsetsBuf) {
1255
+ state.offsetsBuf.destroy();
1256
+ state.offsetsBuf = null;
1257
+ }
1258
+ if (state.modelMatrixCol0Buf) {
1259
+ state.modelMatrixCol0Buf.destroy();
1260
+ state.modelMatrixCol0Buf = null;
1261
+ }
1262
+ if (state.modelMatrixCol1Buf) {
1263
+ state.modelMatrixCol1Buf.destroy();
1264
+ state.modelMatrixCol1Buf = null;
1265
+ }
1266
+ if (state.modelMatrixCol2Buf) {
1267
+ state.modelMatrixCol2Buf.destroy();
1268
+ state.modelMatrixCol2Buf = null;
1269
+ }
1270
+ if (state.modelNormalMatrixCol0Buf) {
1271
+ state.modelNormalMatrixCol0Buf.destroy();
1272
+ state.modelNormalMatrixCol0Buf = null;
1273
+ }
1274
+ if (state.modelNormalMatrixCol1Buf) {
1275
+ state.modelNormalMatrixCol1Buf.destroy();
1276
+ state.modelNormalMatrixCol1Buf = null;
1277
+ }
1278
+ if (state.modelNormalMatrixCol2Buf) {
1279
+ state.modelNormalMatrixCol2Buf.destroy();
1280
+ state.modelNormalMatrixCol2Buf = null;
1281
+ }
1282
+ if (state.pickColorsBuf) {
1283
+ state.pickColorsBuf.destroy();
1284
+ state.pickColorsBuf = null;
1285
+ }
1286
+ state.destroy();
1287
+ this._state = null;
1288
+ }
1289
+ }