WebXRFeaturePointSystem.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import { WebXRFeaturesManager, WebXRFeatureName } from "../webXRFeaturesManager.js";
  2. import { Observable } from "../../Misc/observable.js";
  3. import { Vector3 } from "../../Maths/math.vector.js";
  4. import { WebXRAbstractFeature } from "./WebXRAbstractFeature.js";
  5. /**
  6. * The feature point system is used to detect feature points from real world geometry.
  7. * This feature is currently experimental and only supported on BabylonNative, and should not be used in the browser.
  8. * The newly introduced API can be seen in webxr.nativeextensions.d.ts and described in FeaturePoints.md.
  9. */
  10. export class WebXRFeaturePointSystem extends WebXRAbstractFeature {
  11. /**
  12. * The current feature point cloud maintained across frames.
  13. */
  14. get featurePointCloud() {
  15. return this._featurePointCloud;
  16. }
  17. /**
  18. * construct the feature point system
  19. * @param _xrSessionManager an instance of xr Session manager
  20. */
  21. constructor(_xrSessionManager) {
  22. super(_xrSessionManager);
  23. this._enabled = false;
  24. this._featurePointCloud = [];
  25. /**
  26. * Observers registered here will be executed whenever new feature points are added (on XRFrame while the session is tracking).
  27. * Will notify the observers about which feature points have been added.
  28. */
  29. this.onFeaturePointsAddedObservable = new Observable();
  30. /**
  31. * Observers registered here will be executed whenever a feature point has been updated (on XRFrame while the session is tracking).
  32. * Will notify the observers about which feature points have been updated.
  33. */
  34. this.onFeaturePointsUpdatedObservable = new Observable();
  35. this.xrNativeFeatureName = "bjsfeature-points";
  36. if (this._xrSessionManager.session) {
  37. this._init();
  38. }
  39. else {
  40. this._xrSessionManager.onXRSessionInit.addOnce(() => {
  41. this._init();
  42. });
  43. }
  44. }
  45. /**
  46. * Detach this feature.
  47. * Will usually be called by the features manager
  48. *
  49. * @returns true if successful.
  50. */
  51. detach() {
  52. if (!super.detach()) {
  53. return false;
  54. }
  55. this.featurePointCloud.length = 0;
  56. return true;
  57. }
  58. /**
  59. * Dispose this feature and all of the resources attached
  60. */
  61. dispose() {
  62. super.dispose();
  63. this._featurePointCloud.length = 0;
  64. this.onFeaturePointsUpdatedObservable.clear();
  65. this.onFeaturePointsAddedObservable.clear();
  66. }
  67. /**
  68. * On receiving a new XR frame if this feature is attached notify observers new feature point data is available.
  69. * @param frame
  70. */
  71. _onXRFrame(frame) {
  72. if (!this.attached || !this._enabled || !frame) {
  73. return;
  74. }
  75. const featurePointRawData = frame.featurePointCloud;
  76. if (!featurePointRawData || featurePointRawData.length === 0) {
  77. return;
  78. }
  79. else {
  80. if (featurePointRawData.length % 5 !== 0) {
  81. throw new Error("Received malformed feature point cloud of length: " + featurePointRawData.length);
  82. }
  83. const numberOfFeaturePoints = featurePointRawData.length / 5;
  84. const updatedFeaturePoints = [];
  85. const addedFeaturePoints = [];
  86. for (let i = 0; i < numberOfFeaturePoints; i++) {
  87. const rawIndex = i * 5;
  88. const id = featurePointRawData[rawIndex + 4];
  89. // IDs should be durable across frames and strictly increasing from 0 up, so use them as indexing into the feature point array.
  90. if (!this._featurePointCloud[id]) {
  91. this._featurePointCloud[id] = { position: new Vector3(), confidenceValue: 0 };
  92. addedFeaturePoints.push(id);
  93. }
  94. else {
  95. updatedFeaturePoints.push(id);
  96. }
  97. // Set the feature point values.
  98. this._featurePointCloud[id].position.x = featurePointRawData[rawIndex];
  99. this._featurePointCloud[id].position.y = featurePointRawData[rawIndex + 1];
  100. this._featurePointCloud[id].position.z = featurePointRawData[rawIndex + 2];
  101. this._featurePointCloud[id].confidenceValue = featurePointRawData[rawIndex + 3];
  102. }
  103. // Signal observers that feature points have been added if necessary.
  104. if (addedFeaturePoints.length > 0) {
  105. this.onFeaturePointsAddedObservable.notifyObservers(addedFeaturePoints);
  106. }
  107. // Signal observers that feature points have been updated if necessary.
  108. if (updatedFeaturePoints.length > 0) {
  109. this.onFeaturePointsUpdatedObservable.notifyObservers(updatedFeaturePoints);
  110. }
  111. }
  112. }
  113. /**
  114. * Initializes the feature. If the feature point feature is not available for this environment do not mark the feature as enabled.
  115. */
  116. _init() {
  117. if (!this._xrSessionManager.session.trySetFeaturePointCloudEnabled || !this._xrSessionManager.session.trySetFeaturePointCloudEnabled(true)) {
  118. // fail silently
  119. return;
  120. }
  121. this._enabled = true;
  122. }
  123. }
  124. /**
  125. * The module's name
  126. */
  127. WebXRFeaturePointSystem.Name = WebXRFeatureName.FEATURE_POINTS;
  128. /**
  129. * The (Babylon) version of this module.
  130. * This is an integer representing the implementation version.
  131. * This number does not correspond to the WebXR specs version
  132. */
  133. WebXRFeaturePointSystem.Version = 1;
  134. // register the plugin
  135. WebXRFeaturesManager.AddWebXRFeature(WebXRFeaturePointSystem.Name, (xrSessionManager) => {
  136. return () => new WebXRFeaturePointSystem(xrSessionManager);
  137. }, WebXRFeaturePointSystem.Version);
  138. //# sourceMappingURL=WebXRFeaturePointSystem.js.map