WebXRFeaturePointSystem.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import { WebXRFeaturesManager, WebXRFeatureName } from "../webXRFeaturesManager";
  2. import { WebXRSessionManager } from "../webXRSessionManager";
  3. import { Observable } from "../../Misc/observable";
  4. import { Vector3 } from "../../Maths/math.vector";
  5. import { WebXRAbstractFeature } from "./WebXRAbstractFeature";
  6. /**
  7. * A babylon interface for a "WebXR" feature point.
  8. * Represents the position and confidence value of a given feature point.
  9. */
  10. export interface IWebXRFeaturePoint {
  11. /**
  12. * Represents the position of the feature point in world space.
  13. */
  14. position : Vector3;
  15. /**
  16. * Represents the confidence value of the feature point in world space. 0 being least confident, and 1 being most confident.
  17. */
  18. confidenceValue : number;
  19. /**
  20. * The ID of the feature point, stable across frames.
  21. */
  22. id : number;
  23. }
  24. /**
  25. * Callback function type definition for GetPointCloud. If the user requests this goes and fetches the point cloud from.
  26. */
  27. type GetPointCloud = () => IWebXRFeaturePoint[];
  28. /**
  29. * The feature point system is used to detect feature points from real world geometry.
  30. * This feature is currently experimental and only supported on BabylonNative, and should not be used in the browser.
  31. * The newly introduced API can be seen in webxr.nativeextensions.d.ts.
  32. */
  33. export class WebXRFeaturePointSystem extends WebXRAbstractFeature {
  34. private _enabled: boolean = false;
  35. private _featurePoints: Array<IWebXRFeaturePoint> | null = null;
  36. /**
  37. * The module's name
  38. */
  39. public static readonly Name = WebXRFeatureName.FEATURE_POINTS;
  40. /**
  41. * The (Babylon) version of this module.
  42. * This is an integer representing the implementation version.
  43. * This number does not correspond to the WebXR specs version
  44. */
  45. public static readonly Version = 1;
  46. /**
  47. * Observers registered here will be executed whenever new feature points are available (on XRFrame while the session is tracking).
  48. */
  49. public onFeaturePointsAvailableObservable: Observable<GetPointCloud> = new Observable();
  50. /**
  51. * construct the feature point system
  52. * @param _xrSessionManager an instance of xr Session manager
  53. */
  54. constructor(_xrSessionManager: WebXRSessionManager) {
  55. super(_xrSessionManager);
  56. if (this._xrSessionManager.session) {
  57. this._init();
  58. } else {
  59. this._xrSessionManager.onXRSessionInit.addOnce(() => {
  60. this._init();
  61. });
  62. }
  63. }
  64. /**
  65. * Detach this feature.
  66. * Will usually be called by the features manager
  67. *
  68. * @returns true if successful.
  69. */
  70. public detach(): boolean {
  71. if (!super.detach()) {
  72. return false;
  73. }
  74. this._featurePoints = null;
  75. return true;
  76. }
  77. /**
  78. * Dispose this feature and all of the resources attached
  79. */
  80. public dispose(): void {
  81. super.dispose();
  82. this._featurePoints = null;
  83. this.onFeaturePointsAvailableObservable.clear();
  84. }
  85. /**
  86. * On receiving a new XR frame if this feature is attached notify observers new feature points are available.
  87. * Include a callback to query the current frame for feature points.
  88. */
  89. protected _onXRFrame(frame: XRFrame) {
  90. if (!this.attached || !this._enabled || !frame) {
  91. return;
  92. }
  93. this._featurePoints = null;
  94. this.onFeaturePointsAvailableObservable.notifyObservers(() => {
  95. if (this._featurePoints) {
  96. return this._featurePoints;
  97. }
  98. let featurePointRawData : number[] | undefined = frame.featurePointCloud;
  99. if (!featurePointRawData) {
  100. return new Array<IWebXRFeaturePoint>();
  101. } else {
  102. let numberOfFeaturePoints : number = featurePointRawData.length / 5;
  103. this._featurePoints = new Array<IWebXRFeaturePoint>(featurePointRawData.length / 5);
  104. for (var i = 0; i < numberOfFeaturePoints; i++) {
  105. let rawIndex : number = i * 5;
  106. this._featurePoints[i] = {
  107. position: new Vector3(
  108. featurePointRawData[rawIndex],
  109. featurePointRawData[rawIndex + 1],
  110. featurePointRawData[rawIndex + 2]),
  111. confidenceValue: featurePointRawData[4],
  112. id: featurePointRawData[5]
  113. };
  114. }
  115. return this._featurePoints;
  116. }
  117. });
  118. }
  119. /**
  120. * Initializes the feature. If the feature point feature is not available for this environment do not mark the feature as enabled.
  121. */
  122. private _init() {
  123. if (!this._xrSessionManager.session.setFeaturePointCloudEnabled || !this._xrSessionManager.session.setFeaturePointCloudEnabled(true)) {
  124. // fail silently
  125. return;
  126. }
  127. this._enabled = true;
  128. }
  129. }
  130. //register the plugin
  131. WebXRFeaturesManager.AddWebXRFeature(
  132. WebXRFeaturePointSystem.Name,
  133. (xrSessionManager) => {
  134. return () => new WebXRFeaturePointSystem(xrSessionManager);
  135. },
  136. WebXRFeaturePointSystem.Version
  137. );