@babylonjs/addons 7.33.0 → 7.34.0

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.
@@ -0,0 +1,464 @@
1
+ import { Matrix, Quaternion, Vector3 } from "@babylonjs/core/Maths/math.js";
2
+ import { Camera } from "@babylonjs/core/Cameras/camera.js";
3
+ import { RenderingGroup } from "@babylonjs/core/Rendering/renderingGroup.js";
4
+ import { Logger } from "@babylonjs/core/Misc/logger.js";
5
+ const _positionUpdateFailMessage = "Failed to update html mesh renderer position due to failure to get canvas rect. HtmlMesh instances may not render correctly";
6
+ const babylonUnitsToPixels = 100;
7
+ // Returns a function that ensures that HtmlMeshes are rendered before all other meshes.
8
+ // Note this will only be applied to group 0.
9
+ // If neither mesh is an HtmlMesh, then the default render order is used
10
+ // This prevents HtmlMeshes from appearing in front of other meshes when they are behind them
11
+ const renderOrderFunc = (defaultRenderOrder) => {
12
+ return (subMeshA, subMeshB) => {
13
+ const meshA = subMeshA.getMesh();
14
+ const meshB = subMeshB.getMesh();
15
+ // Use property check instead of instanceof since it is less expensive and
16
+ // this will be called many times per frame
17
+ const meshAIsHtmlMesh = meshA["isHtmlMesh"];
18
+ const meshBIsHtmlMesh = meshB["isHtmlMesh"];
19
+ if (meshAIsHtmlMesh) {
20
+ return meshBIsHtmlMesh ? (meshA.absolutePosition.z <= meshB.absolutePosition.z ? 1 : -1) : -1;
21
+ }
22
+ else {
23
+ return meshBIsHtmlMesh ? 1 : defaultRenderOrder(subMeshA, subMeshB);
24
+ }
25
+ };
26
+ };
27
+ /**
28
+ * An instance of this is required to render HtmlMeshes in the scene.
29
+ * if using HtmlMeshes, you must not set render order for group 0 using
30
+ * scene.setRenderingOrder. You must instead pass the compare functions
31
+ * to the HtmlMeshRenderer constructor. If you do not, then your render
32
+ * order will be overwritten if the HtmlMeshRenderer is created after and
33
+ * the HtmlMeshes will not render correctly (they will appear in front of
34
+ * meshes that are actually in front of them) if the HtmlMeshRenderer is
35
+ * created before.
36
+ */
37
+ export class HtmlMeshRenderer {
38
+ /**
39
+ * Contruct an instance of HtmlMeshRenderer
40
+ * @param scene
41
+ * @param options object containing the following optional properties:
42
+ * @returns
43
+ */
44
+ constructor(scene, { parentContainerId = null, _containerId = "css-container", enableOverlayRender = true, defaultOpaqueRenderOrder = RenderingGroup.PainterSortCompare, defaultAlphaTestRenderOrder = RenderingGroup.PainterSortCompare, defaultTransparentRenderOrder = RenderingGroup.defaultTransparentSortCompare, } = {}) {
45
+ this._cache = {
46
+ cameraData: { fov: 0, position: new Vector3(), style: "" },
47
+ htmlMeshData: new WeakMap(),
48
+ };
49
+ this._width = 0;
50
+ this._height = 0;
51
+ this._heightHalf = 0;
52
+ // Create some refs to avoid creating new objects every frame
53
+ this._temp = {
54
+ scaleTransform: new Vector3(),
55
+ rotationTransform: new Quaternion(),
56
+ positionTransform: new Vector3(),
57
+ objectMatrix: Matrix.Identity(),
58
+ cameraWorldMatrix: Matrix.Identity(),
59
+ cameraRotationMatrix: Matrix.Identity(),
60
+ cameraWorldMatrixAsArray: new Array(16),
61
+ };
62
+ // Keep track of DPR so we can resize if DPR changes
63
+ // Otherwise the DOM content will scale, but the mesh won't
64
+ this._lastDevicePixelRatio = window.devicePixelRatio;
65
+ // Keep track of camera matrix changes so we only update the
66
+ // DOM element styles when necessary
67
+ this._cameraMatrixUpdated = true;
68
+ // Keep track of position changes so we only update the DOM element
69
+ // styles when necessary
70
+ this._previousCanvasDocumentPosition = {
71
+ top: 0,
72
+ left: 0,
73
+ };
74
+ this._renderObserver = null;
75
+ this._onCameraMatrixChanged = (camera) => {
76
+ this._cameraWorldMatrix = camera.getWorldMatrix();
77
+ this._cameraMatrixUpdated = true;
78
+ };
79
+ // Requires a browser to work. Only init if we are in a browser
80
+ if (typeof document === "undefined") {
81
+ return;
82
+ }
83
+ this._containerId = _containerId;
84
+ this._init(scene, parentContainerId, enableOverlayRender, defaultOpaqueRenderOrder, defaultAlphaTestRenderOrder, defaultTransparentRenderOrder);
85
+ }
86
+ /**
87
+ * Dispose of the HtmlMeshRenderer
88
+ */
89
+ dispose() {
90
+ if (this._renderObserver) {
91
+ this._renderObserver.remove();
92
+ this._renderObserver = null;
93
+ }
94
+ this._overlayElements?.container.remove();
95
+ this._overlayElements = null;
96
+ this._inSceneElements?.container.remove();
97
+ this._inSceneElements = null;
98
+ }
99
+ _init(scene, parentContainerId, enableOverlayRender, defaultOpaqueRenderOrder, defaultAlphaTestRenderOrder, defaultTransparentRenderOrder) {
100
+ // Requires a browser to work. Only init if we are in a browser
101
+ if (typeof document === "undefined") {
102
+ return;
103
+ }
104
+ // Create the DOM containers
105
+ let parentContainer = parentContainerId ? document.getElementById(parentContainerId) : document.body;
106
+ if (!parentContainer) {
107
+ parentContainer = document.body;
108
+ }
109
+ // if the container already exists, then remove it
110
+ const inSceneContainerId = `${this._containerId}_in_scene`;
111
+ this._inSceneElements = this._createRenderLayerElements(inSceneContainerId);
112
+ parentContainer.insertBefore(this._inSceneElements.container, parentContainer.firstChild);
113
+ if (enableOverlayRender) {
114
+ const overlayContainerId = `${this._containerId}_overlay`;
115
+ this._overlayElements = this._createRenderLayerElements(overlayContainerId);
116
+ const zIndex = +(scene.getEngine().getRenderingCanvas().style.zIndex ?? "0") + 1;
117
+ this._overlayElements.container.style.zIndex = `${zIndex}`;
118
+ this._overlayElements.container.style.pointerEvents = "none";
119
+ parentContainer.insertBefore(this._overlayElements.container, parentContainer.firstChild);
120
+ }
121
+ this._engine = scene.getEngine();
122
+ const clientRect = this._engine.getRenderingCanvasClientRect();
123
+ if (!clientRect) {
124
+ throw new Error("Failed to get client rect for rendering canvas");
125
+ }
126
+ // Set the size and resize behavior
127
+ this._setSize(clientRect.width, clientRect.height);
128
+ this._engine.onResizeObservable.add(() => {
129
+ const clientRect = this._engine.getRenderingCanvasClientRect();
130
+ if (clientRect) {
131
+ this._setSize(clientRect.width, clientRect.height);
132
+ }
133
+ });
134
+ let projectionObs;
135
+ let matrixObs;
136
+ const observeCamera = () => {
137
+ const camera = scene.activeCamera;
138
+ if (camera) {
139
+ projectionObs = camera.onProjectionMatrixChangedObservable.add(() => {
140
+ this._onCameraMatrixChanged(camera);
141
+ });
142
+ matrixObs = camera.onViewMatrixChangedObservable.add(() => {
143
+ this._onCameraMatrixChanged(camera);
144
+ });
145
+ }
146
+ };
147
+ observeCamera();
148
+ scene.onActiveCameraChanged.add(() => {
149
+ if (projectionObs) {
150
+ scene.activeCamera?.onProjectionMatrixChangedObservable.remove(projectionObs);
151
+ }
152
+ if (matrixObs) {
153
+ scene.activeCamera?.onViewMatrixChangedObservable.remove(matrixObs);
154
+ }
155
+ observeCamera();
156
+ });
157
+ // We need to make sure that HtmlMeshes are rendered before all other meshes
158
+ // so that they don't appear in front of meshes that are actually in front of them
159
+ // Updating the render order isn't ideal, but it is the only way to acheive this
160
+ // The implication is that an app using the HtmlMeshRendered must set the scene render order
161
+ // via the HtmlMeshRendered constructor
162
+ const opaqueRenderOrder = renderOrderFunc(defaultOpaqueRenderOrder);
163
+ const alphaTestRenderOrder = renderOrderFunc(defaultAlphaTestRenderOrder);
164
+ const transparentRenderOrder = renderOrderFunc(defaultTransparentRenderOrder);
165
+ scene.setRenderingOrder(0, opaqueRenderOrder, alphaTestRenderOrder, transparentRenderOrder);
166
+ this._renderObserver = scene.onBeforeRenderObservable.add(() => {
167
+ this._render(scene, scene.activeCamera);
168
+ });
169
+ }
170
+ _createRenderLayerElements(containerId) {
171
+ const existingContainer = document.getElementById(containerId);
172
+ if (existingContainer) {
173
+ existingContainer.remove();
174
+ }
175
+ const container = document.createElement("div");
176
+ container.id = containerId;
177
+ container.style.position = "absolute";
178
+ container.style.width = "100%";
179
+ container.style.height = "100%";
180
+ container.style.zIndex = "-1";
181
+ const domElement = document.createElement("div");
182
+ domElement.style.overflow = "hidden";
183
+ const cameraElement = document.createElement("div");
184
+ cameraElement.style.webkitTransformStyle = "preserve-3d";
185
+ cameraElement.style.transformStyle = "preserve-3d";
186
+ cameraElement.style.pointerEvents = "none";
187
+ domElement.appendChild(cameraElement);
188
+ container.appendChild(domElement);
189
+ return {
190
+ container,
191
+ domElement,
192
+ cameraElement,
193
+ };
194
+ }
195
+ _getSize() {
196
+ return {
197
+ width: this._width,
198
+ height: this._height,
199
+ };
200
+ }
201
+ _setSize(width, height) {
202
+ this._width = width;
203
+ this._height = height;
204
+ this._heightHalf = this._height / 2;
205
+ if (!this._inSceneElements || !this._overlayElements) {
206
+ return;
207
+ }
208
+ const domElements = [this._inSceneElements.domElement, this._overlayElements.domElement, this._inSceneElements.cameraElement, this._overlayElements.cameraElement];
209
+ domElements.forEach((dom) => {
210
+ if (dom) {
211
+ dom.style.width = `${width}px`;
212
+ dom.style.height = `${height}px`;
213
+ }
214
+ });
215
+ }
216
+ // prettier-ignore
217
+ _getCameraCSSMatrix(matrix) {
218
+ const elements = matrix.m;
219
+ return `matrix3d(${this._epsilon(elements[0])},${this._epsilon(-elements[1])},${this._epsilon(elements[2])},${this._epsilon(elements[3])},${this._epsilon(elements[4])},${this._epsilon(-elements[5])},${this._epsilon(elements[6])},${this._epsilon(elements[7])},${this._epsilon(elements[8])},${this._epsilon(-elements[9])},${this._epsilon(elements[10])},${this._epsilon(elements[11])},${this._epsilon(elements[12])},${this._epsilon(-elements[13])},${this._epsilon(elements[14])},${this._epsilon(elements[15])})`;
220
+ }
221
+ // Convert a Babylon world matrix to a CSS matrix
222
+ // This also handles conversion from BJS left handed coords
223
+ // to CSS right handed coords
224
+ // prettier-ignore
225
+ _getHtmlContentCSSMatrix(matrix, useRightHandedSystem) {
226
+ const elements = matrix.m;
227
+ // In a right handed coordinate system, the elements 11 to 14 have to change their direction
228
+ const direction = useRightHandedSystem ? -1 : 1;
229
+ const matrix3d = `matrix3d(${this._epsilon(elements[0])},${this._epsilon(elements[1])},${this._epsilon(elements[2] * -direction)},${this._epsilon(elements[3])},${this._epsilon(-elements[4])},${this._epsilon(-elements[5])},${this._epsilon(elements[6] * direction)},${this._epsilon(-elements[7])},${this._epsilon(elements[8] * -direction)},${this._epsilon(elements[9] * -direction)},${this._epsilon(elements[10])},${this._epsilon(elements[11] * direction)},${this._epsilon(elements[12] * direction)},${this._epsilon(elements[13] * direction)},${this._epsilon(elements[14] * direction)},${this._epsilon(elements[15])})`;
230
+ return matrix3d;
231
+ }
232
+ _getTransformationMatrix(htmlMesh, useRightHandedSystem) {
233
+ // Get the camera world matrix
234
+ // Make sure the camera world matrix is up to date
235
+ if (!this._cameraWorldMatrix) {
236
+ this._cameraWorldMatrix = htmlMesh.getScene().activeCamera?.getWorldMatrix();
237
+ }
238
+ if (!this._cameraWorldMatrix) {
239
+ return Matrix.Identity();
240
+ }
241
+ const objectWorldMatrix = htmlMesh.getWorldMatrix();
242
+ // Scale the object matrix by the base scale factor for the mesh
243
+ // which is the ratio of the mesh width/height to the renderer
244
+ // width/height divided by the babylon units to pixels ratio
245
+ let widthScaleFactor = 1;
246
+ let heightScaleFactor = 1;
247
+ if (htmlMesh.sourceWidth && htmlMesh.sourceHeight) {
248
+ widthScaleFactor = htmlMesh.width / (htmlMesh.sourceWidth / babylonUnitsToPixels);
249
+ heightScaleFactor = htmlMesh.height / (htmlMesh.sourceHeight / babylonUnitsToPixels);
250
+ }
251
+ // Apply the scale to the object's world matrix. Note we aren't scaling
252
+ // the object, just getting a matrix as though it were scaled, so we can
253
+ // scale the content
254
+ const scaleTransform = this._temp.scaleTransform;
255
+ const rotationTransform = this._temp.rotationTransform;
256
+ const positionTransform = this._temp.positionTransform;
257
+ const scaledAndTranslatedObjectMatrix = this._temp.objectMatrix;
258
+ objectWorldMatrix.decompose(scaleTransform, rotationTransform, positionTransform);
259
+ scaleTransform.x *= widthScaleFactor;
260
+ scaleTransform.y *= heightScaleFactor;
261
+ Matrix.ComposeToRef(scaleTransform, rotationTransform, positionTransform, scaledAndTranslatedObjectMatrix);
262
+ // Adjust direction of 12 and 13 of the transformation matrix based on the handedness of the system
263
+ const direction = useRightHandedSystem ? -1 : 1;
264
+ // Adjust translation values to be from camera vs world origin
265
+ // Note that we are also adjusting these values to be pixels vs Babylon units
266
+ const position = htmlMesh.getAbsolutePosition();
267
+ scaledAndTranslatedObjectMatrix.setRowFromFloats(3, (-this._cameraWorldMatrix.m[12] + position.x) * babylonUnitsToPixels * direction, (-this._cameraWorldMatrix.m[13] + position.y) * babylonUnitsToPixels * direction, (this._cameraWorldMatrix.m[14] - position.z) * babylonUnitsToPixels, this._cameraWorldMatrix.m[15] * 0.00001 * babylonUnitsToPixels);
268
+ // Adjust other values to be pixels vs Babylon units
269
+ scaledAndTranslatedObjectMatrix.multiplyAtIndex(3, babylonUnitsToPixels);
270
+ scaledAndTranslatedObjectMatrix.multiplyAtIndex(7, babylonUnitsToPixels);
271
+ scaledAndTranslatedObjectMatrix.multiplyAtIndex(11, babylonUnitsToPixels);
272
+ return scaledAndTranslatedObjectMatrix;
273
+ }
274
+ _renderHtmlMesh(htmlMesh, useRightHandedSystem) {
275
+ if (!htmlMesh.element || !htmlMesh.element.firstElementChild) {
276
+ // nothing to render, so bail
277
+ return;
278
+ }
279
+ // We need to ensure html mesh data is initialized before
280
+ // computing the base scale factor
281
+ let htmlMeshData = this._cache.htmlMeshData.get(htmlMesh);
282
+ if (!htmlMeshData) {
283
+ htmlMeshData = { style: "" };
284
+ this._cache.htmlMeshData.set(htmlMesh, htmlMeshData);
285
+ }
286
+ const cameraElement = htmlMesh._isCanvasOverlay ? this._overlayElements?.cameraElement : this._inSceneElements?.cameraElement;
287
+ if (htmlMesh.element.parentNode !== cameraElement) {
288
+ cameraElement.appendChild(htmlMesh.element);
289
+ }
290
+ // If the htmlMesh content has changed, update the base scale factor
291
+ if (htmlMesh.requiresUpdate) {
292
+ this._updateBaseScaleFactor(htmlMesh);
293
+ }
294
+ // Get the transformation matrix for the html mesh
295
+ const scaledAndTranslatedObjectMatrix = this._getTransformationMatrix(htmlMesh, useRightHandedSystem);
296
+ let style = `translate(-50%, -50%) ${this._getHtmlContentCSSMatrix(scaledAndTranslatedObjectMatrix, useRightHandedSystem)}`;
297
+ // In a right handed system, screens are on the wrong side of the mesh, so we have to rotate by Math.PI which results in the matrix3d seen below
298
+ style += `${useRightHandedSystem ? "matrix3d(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1)" : ""}`;
299
+ if (htmlMeshData.style !== style) {
300
+ htmlMesh.element.style.webkitTransform = style;
301
+ htmlMesh.element.style.transform = style;
302
+ }
303
+ htmlMesh._markAsUpdated();
304
+ }
305
+ _render(scene, camera) {
306
+ let needsUpdate = false;
307
+ const useRightHandedSystem = scene.useRightHandedSystem;
308
+ // Update the container position and size if necessary
309
+ this._updateContainerPositionIfNeeded();
310
+ // Check for a camera change
311
+ if (this._cameraMatrixUpdated) {
312
+ this._cameraMatrixUpdated = false;
313
+ needsUpdate = true;
314
+ }
315
+ // If the camera position has changed, then we also need to update
316
+ if (camera.position.x !== this._cache.cameraData.position.x ||
317
+ camera.position.y !== this._cache.cameraData.position.y ||
318
+ camera.position.z !== this._cache.cameraData.position.z) {
319
+ this._cache.cameraData.position.copyFrom(camera.position);
320
+ needsUpdate = true;
321
+ }
322
+ // Check for a dpr change
323
+ if (window.devicePixelRatio !== this._lastDevicePixelRatio) {
324
+ this._lastDevicePixelRatio = window.devicePixelRatio;
325
+ Logger.Log("In render - dpr changed: ", this._lastDevicePixelRatio);
326
+ needsUpdate = true;
327
+ }
328
+ // Check if any meshes need to be updated
329
+ const meshesNeedingUpdate = scene.meshes.filter((mesh) => mesh["isHtmlMesh"] && (needsUpdate || mesh.requiresUpdate));
330
+ needsUpdate = needsUpdate || meshesNeedingUpdate.length > 0;
331
+ if (!needsUpdate) {
332
+ return;
333
+ }
334
+ // Get a projection matrix for the camera
335
+ const projectionMatrix = camera.getProjectionMatrix();
336
+ const fov = projectionMatrix.m[5] * this._heightHalf;
337
+ if (this._cache.cameraData.fov !== fov) {
338
+ if (camera.mode == Camera.PERSPECTIVE_CAMERA) {
339
+ [this._overlayElements?.domElement, this._inSceneElements?.domElement].forEach((el) => {
340
+ if (el) {
341
+ el.style.webkitPerspective = fov + "px";
342
+ el.style.perspective = fov + "px";
343
+ }
344
+ });
345
+ }
346
+ else {
347
+ [this._overlayElements?.domElement, this._inSceneElements?.domElement].forEach((el) => {
348
+ if (el) {
349
+ el.style.webkitPerspective = "";
350
+ el.style.perspective = "";
351
+ }
352
+ });
353
+ }
354
+ this._cache.cameraData.fov = fov;
355
+ }
356
+ // Get the CSS matrix for the camera (which will include any camera rotation)
357
+ if (camera.parent === null) {
358
+ camera.computeWorldMatrix();
359
+ }
360
+ const cameraMatrixWorld = this._temp.cameraWorldMatrix;
361
+ cameraMatrixWorld.copyFrom(camera.getWorldMatrix());
362
+ const cameraRotationMatrix = this._temp.cameraRotationMatrix;
363
+ cameraMatrixWorld.getRotationMatrix().transposeToRef(cameraRotationMatrix);
364
+ const cameraMatrixWorldAsArray = this._temp.cameraWorldMatrixAsArray;
365
+ cameraMatrixWorld.copyToArray(cameraMatrixWorldAsArray);
366
+ // For a few values, we have to adjust the direction based on the handedness of the system
367
+ const direction = useRightHandedSystem ? 1 : -1;
368
+ cameraMatrixWorldAsArray[1] = cameraRotationMatrix.m[1];
369
+ cameraMatrixWorldAsArray[2] = cameraRotationMatrix.m[2] * direction;
370
+ cameraMatrixWorldAsArray[4] = cameraRotationMatrix.m[4] * direction;
371
+ cameraMatrixWorldAsArray[6] = cameraRotationMatrix.m[6] * direction;
372
+ cameraMatrixWorldAsArray[8] = cameraRotationMatrix.m[8] * direction;
373
+ cameraMatrixWorldAsArray[9] = cameraRotationMatrix.m[9] * direction;
374
+ Matrix.FromArrayToRef(cameraMatrixWorldAsArray, 0, cameraMatrixWorld);
375
+ const cameraCSSMatrix = this._getCameraCSSMatrix(cameraMatrixWorld);
376
+ const style = cameraCSSMatrix;
377
+ if (this._cache.cameraData.style !== style) {
378
+ [this._inSceneElements?.cameraElement, this._overlayElements?.cameraElement].forEach((el) => {
379
+ if (el) {
380
+ el.style.webkitTransform = style;
381
+ el.style.transform = style;
382
+ }
383
+ });
384
+ this._cache.cameraData.style = style;
385
+ }
386
+ // _Render objects if necessary
387
+ meshesNeedingUpdate.forEach((mesh) => {
388
+ this._renderHtmlMesh(mesh, useRightHandedSystem);
389
+ });
390
+ }
391
+ _updateBaseScaleFactor(htmlMesh) {
392
+ // Get screen width and height
393
+ let screenWidth = this._width;
394
+ let screenHeight = this._height;
395
+ // Calculate aspect ratios
396
+ const htmlMeshAspectRatio = (htmlMesh.width || 1) / (htmlMesh.height || 1);
397
+ const screenAspectRatio = screenWidth / screenHeight;
398
+ // Adjust screen dimensions based on aspect ratios
399
+ if (htmlMeshAspectRatio > screenAspectRatio) {
400
+ // If the HTML mesh is wider relative to its height than the screen, adjust the screen width
401
+ screenWidth = screenHeight * htmlMeshAspectRatio;
402
+ }
403
+ else {
404
+ // If the HTML mesh is taller relative to its width than the screen, adjust the screen height
405
+ screenHeight = screenWidth / htmlMeshAspectRatio;
406
+ }
407
+ // Set content to fill screen so we get max resolution when it is shrunk to fit the mesh
408
+ htmlMesh.setContentSizePx(screenWidth, screenHeight);
409
+ }
410
+ _updateContainerPositionIfNeeded() {
411
+ // Determine if the canvas has moved on the screen
412
+ const canvasRect = this._engine.getRenderingCanvasClientRect();
413
+ // canvas rect may be null if layout not complete
414
+ if (!canvasRect) {
415
+ Logger.Warn(_positionUpdateFailMessage);
416
+ return;
417
+ }
418
+ const scrollTop = window.scrollY;
419
+ const scrollLeft = window.scrollX;
420
+ const canvasDocumentTop = canvasRect.top + scrollTop;
421
+ const canvasDocumentLeft = canvasRect.left + scrollLeft;
422
+ if (this._previousCanvasDocumentPosition.top !== canvasDocumentTop || this._previousCanvasDocumentPosition.left !== canvasDocumentLeft) {
423
+ this._previousCanvasDocumentPosition.top = canvasDocumentTop;
424
+ this._previousCanvasDocumentPosition.left = canvasDocumentLeft;
425
+ [this._inSceneElements?.container, this._overlayElements?.container].forEach((container) => {
426
+ if (!container) {
427
+ return;
428
+ }
429
+ // set the top and left of the css container to match the canvas
430
+ const containerParent = container.offsetParent;
431
+ const parentRect = containerParent.getBoundingClientRect();
432
+ const parentDocumentTop = parentRect.top + scrollTop;
433
+ const parentDocumentLeft = parentRect.left + scrollLeft;
434
+ const ancestorMarginsAndPadding = this._getAncestorMarginsAndPadding(containerParent);
435
+ // Add the body margin
436
+ const bodyStyle = window.getComputedStyle(document.body);
437
+ const bodyMarginTop = parseInt(bodyStyle.marginTop, 10);
438
+ const bodyMarginLeft = parseInt(bodyStyle.marginLeft, 10);
439
+ container.style.top = `${canvasDocumentTop - parentDocumentTop - ancestorMarginsAndPadding.marginTop + ancestorMarginsAndPadding.paddingTop + bodyMarginTop}px`;
440
+ container.style.left = `${canvasDocumentLeft - parentDocumentLeft - ancestorMarginsAndPadding.marginLeft + ancestorMarginsAndPadding.paddingLeft + bodyMarginLeft}px`;
441
+ });
442
+ }
443
+ }
444
+ _epsilon(value) {
445
+ return Math.abs(value) < 1e-10 ? 0 : value;
446
+ }
447
+ // Get total margins and padding for an element, excluding the body and document margins
448
+ _getAncestorMarginsAndPadding(element) {
449
+ let marginTop = 0;
450
+ let marginLeft = 0;
451
+ let paddingTop = 0;
452
+ let paddingLeft = 0;
453
+ while (element && element !== document.body && element !== document.documentElement) {
454
+ const style = window.getComputedStyle(element);
455
+ marginTop += parseInt(style.marginTop, 10);
456
+ marginLeft += parseInt(style.marginLeft, 10);
457
+ paddingTop += parseInt(style.paddingTop, 10);
458
+ paddingLeft += parseInt(style.paddingLeft, 10);
459
+ element = element.offsetParent;
460
+ }
461
+ return { marginTop, marginLeft, paddingTop, paddingLeft };
462
+ }
463
+ }
464
+ //# sourceMappingURL=htmlMeshRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"htmlMeshRenderer.js","sourceRoot":"","sources":["../../../../dev/addons/src/htmlMesh/htmlMeshRenderer.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Scene } from \"core/scene\";\r\nimport { Matrix, Quaternion, Vector3 } from \"core/Maths/math\";\r\n\r\nimport type { HtmlMesh } from \"./htmlMesh\";\r\nimport { Camera } from \"core/Cameras/camera\";\r\nimport type { SubMesh } from \"core/Meshes/subMesh\";\r\nimport { RenderingGroup } from \"core/Rendering/renderingGroup\";\r\n\r\nimport type { Observer } from \"core/Misc/observable\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport type { AbstractEngine } from \"core/Engines\";\r\n\r\nconst _positionUpdateFailMessage = \"Failed to update html mesh renderer position due to failure to get canvas rect. HtmlMesh instances may not render correctly\";\r\nconst babylonUnitsToPixels = 100;\r\n\r\n/**\r\n * A function that compares two submeshes and returns a number indicating which\r\n * should be rendered first.\r\n */\r\ntype RenderOrderFunction = (subMeshA: SubMesh, subMeshB: SubMesh) => number;\r\n\r\ntype RenderLayerElements = {\r\n container: HTMLElement;\r\n domElement: HTMLElement;\r\n cameraElement: HTMLElement;\r\n};\r\n\r\n// Returns a function that ensures that HtmlMeshes are rendered before all other meshes.\r\n// Note this will only be applied to group 0.\r\n// If neither mesh is an HtmlMesh, then the default render order is used\r\n// This prevents HtmlMeshes from appearing in front of other meshes when they are behind them\r\nconst renderOrderFunc = (defaultRenderOrder: RenderOrderFunction): RenderOrderFunction => {\r\n return (subMeshA: SubMesh, subMeshB: SubMesh) => {\r\n const meshA = subMeshA.getMesh();\r\n const meshB = subMeshB.getMesh();\r\n\r\n // Use property check instead of instanceof since it is less expensive and\r\n // this will be called many times per frame\r\n const meshAIsHtmlMesh = (meshA as any)[\"isHtmlMesh\"];\r\n const meshBIsHtmlMesh = (meshB as any)[\"isHtmlMesh\"];\r\n if (meshAIsHtmlMesh) {\r\n return meshBIsHtmlMesh ? (meshA.absolutePosition.z <= meshB.absolutePosition.z ? 1 : -1) : -1;\r\n } else {\r\n return meshBIsHtmlMesh ? 1 : defaultRenderOrder(subMeshA, subMeshB);\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * An instance of this is required to render HtmlMeshes in the scene.\r\n * if using HtmlMeshes, you must not set render order for group 0 using\r\n * scene.setRenderingOrder. You must instead pass the compare functions\r\n * to the HtmlMeshRenderer constructor. If you do not, then your render\r\n * order will be overwritten if the HtmlMeshRenderer is created after and\r\n * the HtmlMeshes will not render correctly (they will appear in front of\r\n * meshes that are actually in front of them) if the HtmlMeshRenderer is\r\n * created before.\r\n */\r\nexport class HtmlMeshRenderer {\r\n private _containerId?: string;\r\n private _inSceneElements?: RenderLayerElements | null;\r\n private _overlayElements?: RenderLayerElements | null;\r\n private _engine: AbstractEngine;\r\n\r\n private _cache = {\r\n cameraData: { fov: 0, position: new Vector3(), style: \"\" },\r\n htmlMeshData: new WeakMap<object, { style: string }>(),\r\n };\r\n private _width = 0;\r\n private _height = 0;\r\n private _heightHalf = 0;\r\n\r\n private _cameraWorldMatrix?: Matrix;\r\n\r\n // Create some refs to avoid creating new objects every frame\r\n private _temp = {\r\n scaleTransform: new Vector3(),\r\n rotationTransform: new Quaternion(),\r\n positionTransform: new Vector3(),\r\n objectMatrix: Matrix.Identity(),\r\n cameraWorldMatrix: Matrix.Identity(),\r\n cameraRotationMatrix: Matrix.Identity(),\r\n cameraWorldMatrixAsArray: new Array(16),\r\n };\r\n\r\n // Keep track of DPR so we can resize if DPR changes\r\n // Otherwise the DOM content will scale, but the mesh won't\r\n private _lastDevicePixelRatio = window.devicePixelRatio;\r\n\r\n // Keep track of camera matrix changes so we only update the\r\n // DOM element styles when necessary\r\n private _cameraMatrixUpdated = true;\r\n\r\n // Keep track of position changes so we only update the DOM element\r\n // styles when necessary\r\n private _previousCanvasDocumentPosition = {\r\n top: 0,\r\n left: 0,\r\n };\r\n\r\n private _renderObserver: Observer<Scene> | null = null;\r\n\r\n /**\r\n * Contruct an instance of HtmlMeshRenderer\r\n * @param scene\r\n * @param options object containing the following optional properties:\r\n * @returns\r\n */\r\n constructor(\r\n scene: Scene,\r\n {\r\n parentContainerId = null,\r\n _containerId = \"css-container\",\r\n enableOverlayRender = true,\r\n defaultOpaqueRenderOrder = RenderingGroup.PainterSortCompare,\r\n defaultAlphaTestRenderOrder = RenderingGroup.PainterSortCompare,\r\n defaultTransparentRenderOrder = RenderingGroup.defaultTransparentSortCompare,\r\n }: {\r\n parentContainerId?: string | null;\r\n _containerId?: string;\r\n defaultOpaqueRenderOrder?: RenderOrderFunction;\r\n defaultAlphaTestRenderOrder?: RenderOrderFunction;\r\n defaultTransparentRenderOrder?: RenderOrderFunction;\r\n enableOverlayRender?: boolean;\r\n } = {}\r\n ) {\r\n // Requires a browser to work. Only init if we are in a browser\r\n if (typeof document === \"undefined\") {\r\n return;\r\n }\r\n this._containerId = _containerId;\r\n this._init(scene, parentContainerId, enableOverlayRender, defaultOpaqueRenderOrder, defaultAlphaTestRenderOrder, defaultTransparentRenderOrder);\r\n }\r\n\r\n /**\r\n * Dispose of the HtmlMeshRenderer\r\n */\r\n public dispose() {\r\n if (this._renderObserver) {\r\n this._renderObserver.remove();\r\n this._renderObserver = null;\r\n }\r\n\r\n this._overlayElements?.container.remove();\r\n this._overlayElements = null;\r\n\r\n this._inSceneElements?.container.remove();\r\n this._inSceneElements = null;\r\n }\r\n\r\n protected _init(\r\n scene: Scene,\r\n parentContainerId: string | null,\r\n enableOverlayRender: boolean,\r\n defaultOpaqueRenderOrder: RenderOrderFunction,\r\n defaultAlphaTestRenderOrder: RenderOrderFunction,\r\n defaultTransparentRenderOrder: RenderOrderFunction\r\n ): void {\r\n // Requires a browser to work. Only init if we are in a browser\r\n if (typeof document === \"undefined\") {\r\n return;\r\n }\r\n\r\n // Create the DOM containers\r\n let parentContainer = parentContainerId ? document.getElementById(parentContainerId) : document.body;\r\n\r\n if (!parentContainer) {\r\n parentContainer = document.body;\r\n }\r\n\r\n // if the container already exists, then remove it\r\n const inSceneContainerId = `${this._containerId}_in_scene`;\r\n this._inSceneElements = this._createRenderLayerElements(inSceneContainerId);\r\n\r\n parentContainer.insertBefore(this._inSceneElements.container, parentContainer.firstChild);\r\n\r\n if (enableOverlayRender) {\r\n const overlayContainerId = `${this._containerId}_overlay`;\r\n this._overlayElements = this._createRenderLayerElements(overlayContainerId);\r\n const zIndex = +(scene.getEngine().getRenderingCanvas()!.style.zIndex ?? \"0\") + 1;\r\n this._overlayElements.container.style.zIndex = `${zIndex}`;\r\n this._overlayElements.container.style.pointerEvents = \"none\";\r\n parentContainer.insertBefore(this._overlayElements.container, parentContainer.firstChild);\r\n }\r\n this._engine = scene.getEngine();\r\n const clientRect = this._engine.getRenderingCanvasClientRect();\r\n if (!clientRect) {\r\n throw new Error(\"Failed to get client rect for rendering canvas\");\r\n }\r\n\r\n // Set the size and resize behavior\r\n this._setSize(clientRect.width, clientRect.height);\r\n\r\n this._engine.onResizeObservable.add(() => {\r\n const clientRect = this._engine.getRenderingCanvasClientRect();\r\n if (clientRect) {\r\n this._setSize(clientRect.width, clientRect.height);\r\n }\r\n });\r\n\r\n let projectionObs: Observer<Camera>;\r\n let matrixObs: Observer<Camera>;\r\n\r\n const observeCamera = () => {\r\n const camera = scene.activeCamera;\r\n if (camera) {\r\n projectionObs = camera.onProjectionMatrixChangedObservable.add(() => {\r\n this._onCameraMatrixChanged(camera);\r\n });\r\n matrixObs = camera.onViewMatrixChangedObservable.add(() => {\r\n this._onCameraMatrixChanged(camera);\r\n });\r\n }\r\n };\r\n\r\n observeCamera();\r\n\r\n scene.onActiveCameraChanged.add(() => {\r\n if (projectionObs) {\r\n scene.activeCamera?.onProjectionMatrixChangedObservable.remove(projectionObs);\r\n }\r\n if (matrixObs) {\r\n scene.activeCamera?.onViewMatrixChangedObservable.remove(matrixObs);\r\n }\r\n observeCamera();\r\n });\r\n\r\n // We need to make sure that HtmlMeshes are rendered before all other meshes\r\n // so that they don't appear in front of meshes that are actually in front of them\r\n // Updating the render order isn't ideal, but it is the only way to acheive this\r\n // The implication is that an app using the HtmlMeshRendered must set the scene render order\r\n // via the HtmlMeshRendered constructor\r\n const opaqueRenderOrder = renderOrderFunc(defaultOpaqueRenderOrder);\r\n const alphaTestRenderOrder = renderOrderFunc(defaultAlphaTestRenderOrder);\r\n const transparentRenderOrder = renderOrderFunc(defaultTransparentRenderOrder);\r\n scene.setRenderingOrder(0, opaqueRenderOrder, alphaTestRenderOrder, transparentRenderOrder);\r\n\r\n this._renderObserver = scene.onBeforeRenderObservable.add(() => {\r\n this._render(scene, scene.activeCamera as Camera);\r\n });\r\n }\r\n\r\n private _createRenderLayerElements(containerId: string): RenderLayerElements {\r\n const existingContainer = document.getElementById(containerId);\r\n if (existingContainer) {\r\n existingContainer.remove();\r\n }\r\n const container = document.createElement(\"div\");\r\n container.id = containerId;\r\n container.style.position = \"absolute\";\r\n container.style.width = \"100%\";\r\n container.style.height = \"100%\";\r\n container.style.zIndex = \"-1\";\r\n\r\n const domElement = document.createElement(\"div\");\r\n domElement.style.overflow = \"hidden\";\r\n\r\n const cameraElement = document.createElement(\"div\");\r\n\r\n cameraElement.style.webkitTransformStyle = \"preserve-3d\";\r\n cameraElement.style.transformStyle = \"preserve-3d\";\r\n\r\n cameraElement.style.pointerEvents = \"none\";\r\n\r\n domElement.appendChild(cameraElement);\r\n container.appendChild(domElement);\r\n return {\r\n container,\r\n domElement,\r\n cameraElement,\r\n };\r\n }\r\n\r\n protected _getSize(): { width: number; height: number } {\r\n return {\r\n width: this._width,\r\n height: this._height,\r\n };\r\n }\r\n\r\n protected _setSize(width: number, height: number): void {\r\n this._width = width;\r\n this._height = height;\r\n this._heightHalf = this._height / 2;\r\n\r\n if (!this._inSceneElements || !this._overlayElements) {\r\n return;\r\n }\r\n\r\n const domElements = [this._inSceneElements!.domElement, this._overlayElements!.domElement, this._inSceneElements!.cameraElement, this._overlayElements!.cameraElement];\r\n domElements.forEach((dom) => {\r\n if (dom) {\r\n dom.style.width = `${width}px`;\r\n dom.style.height = `${height}px`;\r\n }\r\n });\r\n }\r\n\r\n // prettier-ignore\r\n protected _getCameraCSSMatrix(matrix: Matrix): string {\r\n const elements = matrix.m;\r\n return `matrix3d(${\r\n this._epsilon( elements[0] )\r\n },${\r\n this._epsilon( - elements[1] )\r\n },${\r\n this._epsilon( elements[2] )\r\n },${\r\n this._epsilon( elements[3] )\r\n },${\r\n this._epsilon( elements[4] )\r\n },${\r\n this._epsilon( - elements[5] )\r\n },${\r\n this._epsilon( elements[6] )\r\n },${\r\n this._epsilon( elements[7] )\r\n },${\r\n this._epsilon( elements[8] )\r\n },${\r\n this._epsilon( - elements[9] )\r\n },${\r\n this._epsilon( elements[10] )\r\n },${\r\n this._epsilon( elements[11] )\r\n },${\r\n this._epsilon( elements[12] )\r\n },${\r\n this._epsilon( - elements[13] )\r\n },${\r\n this._epsilon( elements[14] )\r\n },${\r\n this._epsilon( elements[15] )\r\n })`;\r\n }\r\n\r\n // Convert a Babylon world matrix to a CSS matrix\r\n // This also handles conversion from BJS left handed coords\r\n // to CSS right handed coords\r\n // prettier-ignore\r\n protected _getHtmlContentCSSMatrix(matrix: Matrix, useRightHandedSystem: boolean): string {\r\n const elements = matrix.m;\r\n // In a right handed coordinate system, the elements 11 to 14 have to change their direction\r\n const direction = useRightHandedSystem ? -1 : 1;\r\n const matrix3d = `matrix3d(${\r\n this._epsilon( elements[0] )\r\n },${\r\n this._epsilon( elements[1] )\r\n },${\r\n this._epsilon( elements[2] * -direction )\r\n },${\r\n this._epsilon( elements[3] )\r\n },${\r\n this._epsilon( - elements[4] )\r\n },${\r\n this._epsilon( - elements[5] )\r\n },${\r\n this._epsilon( elements[6] * direction )\r\n },${\r\n this._epsilon( - elements[7] )\r\n },${\r\n this._epsilon( elements[8] * -direction )\r\n },${\r\n this._epsilon( elements[9] * -direction )\r\n },${\r\n this._epsilon( elements[10] )\r\n },${\r\n this._epsilon( elements[11] * direction )\r\n },${\r\n this._epsilon( elements[12] * direction )\r\n },${\r\n this._epsilon( elements[13] * direction )\r\n },${\r\n this._epsilon( elements[14] * direction )\r\n },${\r\n this._epsilon( elements[15] )\r\n })`;\r\n return matrix3d;\r\n }\r\n\r\n protected _getTransformationMatrix(htmlMesh: HtmlMesh, useRightHandedSystem: boolean): Matrix {\r\n // Get the camera world matrix\r\n // Make sure the camera world matrix is up to date\r\n if (!this._cameraWorldMatrix) {\r\n this._cameraWorldMatrix = htmlMesh.getScene().activeCamera?.getWorldMatrix();\r\n }\r\n if (!this._cameraWorldMatrix) {\r\n return Matrix.Identity();\r\n }\r\n\r\n const objectWorldMatrix = htmlMesh.getWorldMatrix();\r\n\r\n // Scale the object matrix by the base scale factor for the mesh\r\n // which is the ratio of the mesh width/height to the renderer\r\n // width/height divided by the babylon units to pixels ratio\r\n let widthScaleFactor = 1;\r\n let heightScaleFactor = 1;\r\n if (htmlMesh.sourceWidth && htmlMesh.sourceHeight) {\r\n widthScaleFactor = htmlMesh.width! / (htmlMesh.sourceWidth / babylonUnitsToPixels);\r\n heightScaleFactor = htmlMesh.height! / (htmlMesh.sourceHeight / babylonUnitsToPixels);\r\n }\r\n\r\n // Apply the scale to the object's world matrix. Note we aren't scaling\r\n // the object, just getting a matrix as though it were scaled, so we can\r\n // scale the content\r\n const scaleTransform = this._temp.scaleTransform;\r\n const rotationTransform = this._temp.rotationTransform;\r\n const positionTransform = this._temp.positionTransform;\r\n const scaledAndTranslatedObjectMatrix = this._temp.objectMatrix;\r\n\r\n objectWorldMatrix.decompose(scaleTransform, rotationTransform, positionTransform);\r\n scaleTransform.x *= widthScaleFactor;\r\n scaleTransform.y *= heightScaleFactor;\r\n\r\n Matrix.ComposeToRef(scaleTransform, rotationTransform, positionTransform, scaledAndTranslatedObjectMatrix);\r\n\r\n // Adjust direction of 12 and 13 of the transformation matrix based on the handedness of the system\r\n const direction = useRightHandedSystem ? -1 : 1;\r\n // Adjust translation values to be from camera vs world origin\r\n // Note that we are also adjusting these values to be pixels vs Babylon units\r\n const position = htmlMesh.getAbsolutePosition();\r\n scaledAndTranslatedObjectMatrix.setRowFromFloats(\r\n 3,\r\n (-this._cameraWorldMatrix.m[12] + position.x) * babylonUnitsToPixels * direction,\r\n (-this._cameraWorldMatrix.m[13] + position.y) * babylonUnitsToPixels * direction,\r\n (this._cameraWorldMatrix.m[14] - position.z) * babylonUnitsToPixels,\r\n this._cameraWorldMatrix.m[15] * 0.00001 * babylonUnitsToPixels\r\n );\r\n\r\n // Adjust other values to be pixels vs Babylon units\r\n scaledAndTranslatedObjectMatrix.multiplyAtIndex(3, babylonUnitsToPixels);\r\n scaledAndTranslatedObjectMatrix.multiplyAtIndex(7, babylonUnitsToPixels);\r\n scaledAndTranslatedObjectMatrix.multiplyAtIndex(11, babylonUnitsToPixels);\r\n\r\n return scaledAndTranslatedObjectMatrix;\r\n }\r\n\r\n protected _renderHtmlMesh(htmlMesh: HtmlMesh, useRightHandedSystem: boolean) {\r\n if (!htmlMesh.element || !htmlMesh.element.firstElementChild) {\r\n // nothing to render, so bail\r\n return;\r\n }\r\n\r\n // We need to ensure html mesh data is initialized before\r\n // computing the base scale factor\r\n let htmlMeshData = this._cache.htmlMeshData.get(htmlMesh);\r\n if (!htmlMeshData) {\r\n htmlMeshData = { style: \"\" };\r\n this._cache.htmlMeshData.set(htmlMesh, htmlMeshData);\r\n }\r\n\r\n const cameraElement = htmlMesh._isCanvasOverlay ? this._overlayElements?.cameraElement : this._inSceneElements?.cameraElement;\r\n\r\n if (htmlMesh.element.parentNode !== cameraElement) {\r\n cameraElement!.appendChild(htmlMesh.element);\r\n }\r\n\r\n // If the htmlMesh content has changed, update the base scale factor\r\n if (htmlMesh.requiresUpdate) {\r\n this._updateBaseScaleFactor(htmlMesh);\r\n }\r\n\r\n // Get the transformation matrix for the html mesh\r\n const scaledAndTranslatedObjectMatrix = this._getTransformationMatrix(htmlMesh, useRightHandedSystem);\r\n\r\n let style = `translate(-50%, -50%) ${this._getHtmlContentCSSMatrix(scaledAndTranslatedObjectMatrix, useRightHandedSystem)}`;\r\n // In a right handed system, screens are on the wrong side of the mesh, so we have to rotate by Math.PI which results in the matrix3d seen below\r\n style += `${useRightHandedSystem ? \"matrix3d(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1)\" : \"\"}`;\r\n\r\n if (htmlMeshData.style !== style) {\r\n htmlMesh.element.style.webkitTransform = style;\r\n htmlMesh.element.style.transform = style;\r\n }\r\n\r\n htmlMesh._markAsUpdated();\r\n }\r\n\r\n protected _render(scene: Scene, camera: Camera) {\r\n let needsUpdate = false;\r\n\r\n const useRightHandedSystem = scene.useRightHandedSystem;\r\n\r\n // Update the container position and size if necessary\r\n this._updateContainerPositionIfNeeded();\r\n\r\n // Check for a camera change\r\n if (this._cameraMatrixUpdated) {\r\n this._cameraMatrixUpdated = false;\r\n needsUpdate = true;\r\n }\r\n\r\n // If the camera position has changed, then we also need to update\r\n if (\r\n camera.position.x !== this._cache.cameraData.position.x ||\r\n camera.position.y !== this._cache.cameraData.position.y ||\r\n camera.position.z !== this._cache.cameraData.position.z\r\n ) {\r\n this._cache.cameraData.position.copyFrom(camera.position);\r\n needsUpdate = true;\r\n }\r\n\r\n // Check for a dpr change\r\n if (window.devicePixelRatio !== this._lastDevicePixelRatio) {\r\n this._lastDevicePixelRatio = window.devicePixelRatio;\r\n Logger.Log(\"In render - dpr changed: \", this._lastDevicePixelRatio);\r\n needsUpdate = true;\r\n }\r\n\r\n // Check if any meshes need to be updated\r\n const meshesNeedingUpdate = scene.meshes.filter((mesh) => (mesh as any)[\"isHtmlMesh\"] && (needsUpdate || (mesh as HtmlMesh).requiresUpdate));\r\n needsUpdate = needsUpdate || meshesNeedingUpdate.length > 0;\r\n\r\n if (!needsUpdate) {\r\n return;\r\n }\r\n\r\n // Get a projection matrix for the camera\r\n const projectionMatrix = camera.getProjectionMatrix();\r\n const fov = projectionMatrix.m[5] * this._heightHalf;\r\n\r\n if (this._cache.cameraData.fov !== fov) {\r\n if (camera.mode == Camera.PERSPECTIVE_CAMERA) {\r\n [this._overlayElements?.domElement, this._inSceneElements?.domElement].forEach((el) => {\r\n if (el) {\r\n el.style.webkitPerspective = fov + \"px\";\r\n el.style.perspective = fov + \"px\";\r\n }\r\n });\r\n } else {\r\n [this._overlayElements?.domElement, this._inSceneElements?.domElement].forEach((el) => {\r\n if (el) {\r\n el.style.webkitPerspective = \"\";\r\n el.style.perspective = \"\";\r\n }\r\n });\r\n }\r\n this._cache.cameraData.fov = fov;\r\n }\r\n\r\n // Get the CSS matrix for the camera (which will include any camera rotation)\r\n if (camera.parent === null) {\r\n camera.computeWorldMatrix();\r\n }\r\n\r\n const cameraMatrixWorld = this._temp.cameraWorldMatrix;\r\n cameraMatrixWorld.copyFrom(camera.getWorldMatrix());\r\n const cameraRotationMatrix = this._temp.cameraRotationMatrix;\r\n cameraMatrixWorld.getRotationMatrix().transposeToRef(cameraRotationMatrix);\r\n\r\n const cameraMatrixWorldAsArray = this._temp.cameraWorldMatrixAsArray;\r\n cameraMatrixWorld.copyToArray(cameraMatrixWorldAsArray);\r\n\r\n // For a few values, we have to adjust the direction based on the handedness of the system\r\n const direction = useRightHandedSystem ? 1 : -1;\r\n\r\n cameraMatrixWorldAsArray[1] = cameraRotationMatrix.m[1];\r\n cameraMatrixWorldAsArray[2] = cameraRotationMatrix.m[2] * direction;\r\n cameraMatrixWorldAsArray[4] = cameraRotationMatrix.m[4] * direction;\r\n cameraMatrixWorldAsArray[6] = cameraRotationMatrix.m[6] * direction;\r\n cameraMatrixWorldAsArray[8] = cameraRotationMatrix.m[8] * direction;\r\n cameraMatrixWorldAsArray[9] = cameraRotationMatrix.m[9] * direction;\r\n\r\n Matrix.FromArrayToRef(cameraMatrixWorldAsArray, 0, cameraMatrixWorld);\r\n\r\n const cameraCSSMatrix = this._getCameraCSSMatrix(cameraMatrixWorld);\r\n const style = cameraCSSMatrix;\r\n\r\n if (this._cache.cameraData.style !== style) {\r\n [this._inSceneElements?.cameraElement, this._overlayElements?.cameraElement].forEach((el) => {\r\n if (el) {\r\n el.style.webkitTransform = style;\r\n el.style.transform = style;\r\n }\r\n });\r\n this._cache.cameraData.style = style;\r\n }\r\n\r\n // _Render objects if necessary\r\n meshesNeedingUpdate.forEach((mesh) => {\r\n this._renderHtmlMesh(mesh as HtmlMesh, useRightHandedSystem);\r\n });\r\n }\r\n\r\n protected _updateBaseScaleFactor(htmlMesh: HtmlMesh) {\r\n // Get screen width and height\r\n let screenWidth = this._width;\r\n let screenHeight = this._height;\r\n\r\n // Calculate aspect ratios\r\n const htmlMeshAspectRatio = (htmlMesh.width || 1) / (htmlMesh.height || 1);\r\n const screenAspectRatio = screenWidth / screenHeight;\r\n\r\n // Adjust screen dimensions based on aspect ratios\r\n if (htmlMeshAspectRatio > screenAspectRatio) {\r\n // If the HTML mesh is wider relative to its height than the screen, adjust the screen width\r\n screenWidth = screenHeight * htmlMeshAspectRatio;\r\n } else {\r\n // If the HTML mesh is taller relative to its width than the screen, adjust the screen height\r\n screenHeight = screenWidth / htmlMeshAspectRatio;\r\n }\r\n\r\n // Set content to fill screen so we get max resolution when it is shrunk to fit the mesh\r\n htmlMesh.setContentSizePx(screenWidth, screenHeight);\r\n }\r\n\r\n protected _updateContainerPositionIfNeeded() {\r\n // Determine if the canvas has moved on the screen\r\n const canvasRect = this._engine.getRenderingCanvasClientRect();\r\n\r\n // canvas rect may be null if layout not complete\r\n if (!canvasRect) {\r\n Logger.Warn(_positionUpdateFailMessage);\r\n return;\r\n }\r\n const scrollTop = window.scrollY;\r\n const scrollLeft = window.scrollX;\r\n const canvasDocumentTop = canvasRect.top + scrollTop;\r\n const canvasDocumentLeft = canvasRect.left + scrollLeft;\r\n\r\n if (this._previousCanvasDocumentPosition.top !== canvasDocumentTop || this._previousCanvasDocumentPosition.left !== canvasDocumentLeft) {\r\n this._previousCanvasDocumentPosition.top = canvasDocumentTop;\r\n this._previousCanvasDocumentPosition.left = canvasDocumentLeft;\r\n\r\n [this._inSceneElements?.container, this._overlayElements?.container].forEach((container) => {\r\n if (!container) {\r\n return;\r\n }\r\n // set the top and left of the css container to match the canvas\r\n const containerParent = container.offsetParent as HTMLElement;\r\n const parentRect = containerParent.getBoundingClientRect();\r\n const parentDocumentTop = parentRect.top + scrollTop;\r\n const parentDocumentLeft = parentRect.left + scrollLeft;\r\n\r\n const ancestorMarginsAndPadding = this._getAncestorMarginsAndPadding(containerParent);\r\n\r\n // Add the body margin\r\n const bodyStyle = window.getComputedStyle(document.body);\r\n const bodyMarginTop = parseInt(bodyStyle.marginTop, 10);\r\n const bodyMarginLeft = parseInt(bodyStyle.marginLeft, 10);\r\n\r\n container.style.top = `${canvasDocumentTop - parentDocumentTop - ancestorMarginsAndPadding.marginTop + ancestorMarginsAndPadding.paddingTop + bodyMarginTop}px`;\r\n container.style.left = `${\r\n canvasDocumentLeft - parentDocumentLeft - ancestorMarginsAndPadding.marginLeft + ancestorMarginsAndPadding.paddingLeft + bodyMarginLeft\r\n }px`;\r\n });\r\n }\r\n }\r\n\r\n protected _onCameraMatrixChanged = (camera: Camera) => {\r\n this._cameraWorldMatrix = camera.getWorldMatrix();\r\n this._cameraMatrixUpdated = true;\r\n };\r\n\r\n private _epsilon(value: number) {\r\n return Math.abs(value) < 1e-10 ? 0 : value;\r\n }\r\n\r\n // Get total margins and padding for an element, excluding the body and document margins\r\n private _getAncestorMarginsAndPadding(element: HTMLElement) {\r\n let marginTop = 0;\r\n let marginLeft = 0;\r\n let paddingTop = 0;\r\n let paddingLeft = 0;\r\n\r\n while (element && element !== document.body && element !== document.documentElement) {\r\n const style = window.getComputedStyle(element);\r\n marginTop += parseInt(style.marginTop, 10);\r\n marginLeft += parseInt(style.marginLeft, 10);\r\n paddingTop += parseInt(style.paddingTop, 10);\r\n paddingLeft += parseInt(style.paddingLeft, 10);\r\n element = element.offsetParent as HTMLElement;\r\n }\r\n\r\n return { marginTop, marginLeft, paddingTop, paddingLeft };\r\n }\r\n}\r\n"]}
@@ -0,0 +1,5 @@
1
+ import { HtmlMeshRenderer } from "./htmlMeshRenderer";
2
+ import { HtmlMesh } from "./htmlMesh";
3
+ import { PointerEventsCaptureBehavior } from "./pointerEventsCaptureBehavior";
4
+ import { FitStrategy } from "./fitStrategy";
5
+ export { HtmlMeshRenderer, HtmlMesh, PointerEventsCaptureBehavior, FitStrategy };
@@ -0,0 +1,7 @@
1
+ import { HtmlMeshRenderer } from "./htmlMeshRenderer.js";
2
+ import { HtmlMesh } from "./htmlMesh.js";
3
+ import { PointerEventsCaptureBehavior } from "./pointerEventsCaptureBehavior.js";
4
+ import { FitStrategy } from "./fitStrategy.js";
5
+ // Export public classes and functions
6
+ export { HtmlMeshRenderer, HtmlMesh, PointerEventsCaptureBehavior, FitStrategy };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../dev/addons/src/htmlMesh/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,sCAAsC;AACtC,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,4BAA4B,EAAE,WAAW,EAAE,CAAC","sourcesContent":["import { HtmlMeshRenderer } from \"./htmlMeshRenderer\";\r\nimport { HtmlMesh } from \"./htmlMesh\";\r\nimport { PointerEventsCaptureBehavior } from \"./pointerEventsCaptureBehavior\";\r\nimport { FitStrategy } from \"./fitStrategy\";\r\n\r\n// Export public classes and functions\r\nexport { HtmlMeshRenderer, HtmlMesh, PointerEventsCaptureBehavior, FitStrategy };\r\n"]}
@@ -0,0 +1,37 @@
1
+ type CaptureReleaseCallback = () => void;
2
+ /**
3
+ * Get the id of the object currently capturing pointer events
4
+ * @returns The id of the object currently capturing pointer events
5
+ * or null if no object is capturing pointer events
6
+ */
7
+ export declare const getCapturingId: () => string | null;
8
+ /**
9
+ * Request that the object with the given id capture pointer events. If there is no current
10
+ * owner, then the request is granted immediately. If there is a current owner, then the request
11
+ * is queued until the current owner releases pointer events.
12
+ * @param requestId An id to identify the request. This id will be used to match the capture
13
+ * request with the release request.
14
+ * @param captureCallback The callback to call when the request is granted and the object is capturing
15
+ * @param releaseCallback The callback to call when the object is no longer capturing pointer events
16
+ */
17
+ export declare const requestCapture: (requestId: string, captureCallback: CaptureReleaseCallback, releaseCallback: CaptureReleaseCallback) => void;
18
+ /**
19
+ * Release pointer events from the object with the given id. If the object is the current owner
20
+ * then pointer events are released immediately. If the object is not the current owner, then the
21
+ * associated capture request is removed from the queue. If there is no matching capture request
22
+ * in the queue, then the release request is added to a list of unmatched release requests and will
23
+ * negate the next capture request with the same id. This is to guard against the possibility that
24
+ * the release request arrived before the capture request.
25
+ * @param requestId The id which should match the id of the capture request
26
+ */
27
+ export declare const requestRelease: (requestId: string | null) => void;
28
+ /**
29
+ * Relase pointer events from the current owner
30
+ */
31
+ export declare const releaseCurrent: () => void;
32
+ declare global {
33
+ interface Window {
34
+ "pointer-events-capture-debug": boolean | null;
35
+ }
36
+ }
37
+ export {};