123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- import { WebXRFeatureName, WebXRFeaturesManager } from "../webXRFeaturesManager.js";
- import { WebXRAbstractFeature } from "./WebXRAbstractFeature.js";
- import { Observable } from "../../Misc/observable.js";
- import { WebGLHardwareTexture } from "../../Engines/WebGL/webGLHardwareTexture.js";
- import { InternalTexture, InternalTextureSource } from "../../Materials/Textures/internalTexture.js";
- import { BaseTexture } from "../../Materials/Textures/baseTexture.js";
- /**
- * WebXR Feature for WebXR raw camera access
- * @since 6.31.0
- * @see https://immersive-web.github.io/raw-camera-access/
- */
- export class WebXRRawCameraAccess extends WebXRAbstractFeature {
- /**
- * Creates a new instance of the feature
- * @param _xrSessionManager the WebXRSessionManager
- * @param options options for the Feature
- */
- constructor(_xrSessionManager, options = {}) {
- super(_xrSessionManager);
- this.options = options;
- this._cachedInternalTextures = [];
- /**
- * This is an array of camera views
- * Note that mostly the array will contain a single view
- * If you want to know the order of the views, use the `viewIndex` array
- */
- this.texturesData = [];
- /**
- * If needed, this array will contain the eye definition of each texture in `texturesArray`
- */
- this.viewIndex = [];
- /**
- * If needed, this array will contain the camera's intrinsics
- * You can use this data to convert from camera space to screen space and vice versa
- */
- this.cameraIntrinsics = [];
- /**
- * An observable that will notify when the camera's textures are updated
- */
- this.onTexturesUpdatedObservable = new Observable();
- this.xrNativeFeatureName = "camera-access";
- }
- attach(force) {
- if (!super.attach(force)) {
- return false;
- }
- this._glContext = this._xrSessionManager.scene.getEngine()._gl;
- this._glBinding = new XRWebGLBinding(this._xrSessionManager.session, this._glContext);
- return true;
- }
- detach() {
- if (!super.detach()) {
- return false;
- }
- this._glBinding = undefined;
- if (!this.options.doNotDisposeOnDetach) {
- this._cachedInternalTextures.forEach((t) => t.dispose());
- this.texturesData.forEach((t) => t.dispose());
- this._cachedInternalTextures.length = 0;
- this.texturesData.length = 0;
- this.cameraIntrinsics.length = 0;
- }
- return true;
- }
- /**
- * Dispose this feature and all of the resources attached
- */
- dispose() {
- super.dispose();
- this.onTexturesUpdatedObservable.clear();
- }
- /**
- * @see https://github.com/immersive-web/raw-camera-access/blob/main/explainer.md
- * @param view the XRView to update
- * @param index the index of the view in the views array
- */
- _updateCameraIntrinsics(view, index) {
- const cameraViewport = {
- width: view.camera.width,
- height: view.camera.height,
- x: 0,
- y: 0,
- };
- const p = view.projectionMatrix;
- // Principal point in pixels (typically at or near the center of the viewport)
- const u0 = ((1 - p[8]) * cameraViewport.width) / 2 + cameraViewport.x;
- const v0 = ((1 - p[9]) * cameraViewport.height) / 2 + cameraViewport.y;
- // Focal lengths in pixels (these are equal for square pixels)
- const ax = (cameraViewport.width / 2) * p[0];
- const ay = (cameraViewport.height / 2) * p[5];
- // Skew factor in pixels (nonzero for rhomboid pixels)
- const gamma = (cameraViewport.width / 2) * p[4];
- this.cameraIntrinsics[index] = {
- u0,
- v0,
- ax,
- ay,
- gamma,
- width: cameraViewport.width,
- height: cameraViewport.height,
- viewportX: cameraViewport.x,
- viewportY: cameraViewport.y,
- };
- }
- _updateInternalTextures(view, index = 0) {
- if (!view.camera) {
- return false;
- }
- this.viewIndex[index] = view.eye;
- const lp = this._glBinding?.getCameraImage(view.camera);
- if (!this._cachedInternalTextures[index]) {
- const internalTexture = new InternalTexture(this._xrSessionManager.scene.getEngine(), InternalTextureSource.Unknown, true);
- internalTexture.isCube = true;
- internalTexture.invertY = false;
- // internalTexture._useSRGBBuffer = this.options.reflectionFormat === "srgba8";
- internalTexture.format = 5;
- internalTexture.generateMipMaps = true;
- internalTexture.type = 1;
- internalTexture.samplingMode = 3;
- internalTexture.width = view.camera.width;
- internalTexture.height = view.camera.height;
- internalTexture._cachedWrapU = 1;
- internalTexture._cachedWrapV = 1;
- internalTexture._hardwareTexture = new WebGLHardwareTexture(lp, this._glContext);
- this._cachedInternalTextures[index] = internalTexture;
- // create the base texture
- const texture = new BaseTexture(this._xrSessionManager.scene);
- texture.name = `WebXR Raw Camera Access (${index})`;
- texture._texture = this._cachedInternalTextures[index];
- this.texturesData[index] = texture;
- // get the camera intrinsics
- this._updateCameraIntrinsics(view, index);
- }
- else {
- // make sure the webgl texture is updated. Should happen automatically
- this._cachedInternalTextures[index]._hardwareTexture?.set(lp);
- }
- this._cachedInternalTextures[index].isReady = true;
- return true;
- }
- _onXRFrame(_xrFrame) {
- const referenceSPace = this._xrSessionManager.referenceSpace;
- const pose = _xrFrame.getViewerPose(referenceSPace);
- if (!pose || !pose.views) {
- return;
- }
- let updated = true;
- pose.views.forEach((view, index) => {
- updated = updated && this._updateInternalTextures(view, index);
- });
- if (updated) {
- this.onTexturesUpdatedObservable.notifyObservers(this.texturesData);
- }
- }
- }
- /**
- * The module's name
- */
- WebXRRawCameraAccess.Name = WebXRFeatureName.RAW_CAMERA_ACCESS;
- /**
- * The (Babylon) version of this module.
- * This is an integer representing the implementation version.
- * This number does not correspond to the WebXR specs version
- */
- WebXRRawCameraAccess.Version = 1;
- WebXRFeaturesManager.AddWebXRFeature(WebXRRawCameraAccess.Name, (xrSessionManager, options) => {
- return () => new WebXRRawCameraAccess(xrSessionManager, options);
- }, WebXRRawCameraAccess.Version, false);
- //# sourceMappingURL=WebXRRawCameraAccess.js.map
|