webXRHTCViveMotionController.ts 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. import {
  2. IMotionControllerLayoutMap,
  3. IMinimalMotionControllerObject,
  4. MotionControllerHandness,
  5. WebXRAbstractMotionController
  6. } from "./webXRAbstractMotionController";
  7. import { Scene } from '../../scene';
  8. import { AbstractMesh } from '../../Meshes/abstractMesh';
  9. import { Mesh } from '../../Meshes/mesh';
  10. import { Quaternion } from '../../Maths/math.vector';
  11. import { WebXRMotionControllerManager } from './webXRMotionControllerManager';
  12. /**
  13. * The motion controller class for the standard HTC-Vive controllers
  14. */
  15. export class WebXRHTCViveMotionController extends WebXRAbstractMotionController {
  16. private _modelRootNode: AbstractMesh;
  17. /**
  18. * The base url used to load the left and right controller models
  19. */
  20. public static MODEL_BASE_URL: string = 'https://controllers.babylonjs.com/vive/';
  21. /**
  22. * File name for the controller model.
  23. */
  24. public static MODEL_FILENAME: string = 'wand.babylon';
  25. public profileId = "htc-vive";
  26. /**
  27. * Create a new Vive motion controller object
  28. * @param scene the scene to use to create this controller
  29. * @param gamepadObject the corresponding gamepad object
  30. * @param handness the handness of the controller
  31. */
  32. constructor(scene: Scene,
  33. gamepadObject: IMinimalMotionControllerObject,
  34. handness: MotionControllerHandness) {
  35. super(scene, HTCViveLayout[handness], gamepadObject, handness);
  36. }
  37. protected _getFilenameAndPath(): { filename: string; path: string; } {
  38. let filename = WebXRHTCViveMotionController.MODEL_FILENAME;
  39. let path = WebXRHTCViveMotionController.MODEL_BASE_URL;
  40. return {
  41. filename,
  42. path
  43. };
  44. }
  45. protected _getModelLoadingConstraints(): boolean {
  46. return true;
  47. }
  48. protected _processLoadedModel(_meshes: AbstractMesh[]): void {
  49. this.getComponentIds().forEach((id) => {
  50. const comp = id && this.getComponent(id);
  51. if (comp) {
  52. comp.onButtonStateChangedObservable.add((component) => {
  53. if (!this.rootMesh || this.disableAnimation) { return; }
  54. switch (id) {
  55. case "xr-standard-trigger":
  56. (<AbstractMesh>(this._modelRootNode.getChildren()[6])).rotation.x = -component.value * 0.15;
  57. return;
  58. case "xr-standard-touchpad":
  59. return;
  60. case "xr-standard-squeeze":
  61. return;
  62. }
  63. }, undefined, true);
  64. }
  65. });
  66. }
  67. protected _setRootMesh(meshes: AbstractMesh[]): void {
  68. this.rootMesh = new Mesh(this.profileId + " " + this.handness, this.scene);
  69. meshes.forEach((mesh) => { mesh.isPickable = false; });
  70. this._modelRootNode = meshes[1];
  71. this._modelRootNode.parent = this.rootMesh;
  72. this.rootMesh.rotationQuaternion = Quaternion.FromEulerAngles(0, Math.PI, 0);
  73. }
  74. protected _updateModel(): void {
  75. // no-op. model is updated using observables.
  76. }
  77. }
  78. // register the profile
  79. WebXRMotionControllerManager.RegisterController("htc-vive", (xrInput: XRInputSource, scene: Scene) => {
  80. return new WebXRHTCViveMotionController(scene, <any>(xrInput.gamepad), xrInput.handedness);
  81. });
  82. // WebXRMotionControllerManager.RegisterController("htc-vive-legacy", (xrInput: XRInputSource, scene: Scene) => {
  83. // return new WebXRHTCViveMotionController(scene, <any>(xrInput.gamepad), xrInput.handedness, true);
  84. // });
  85. const HTCViveLayout: IMotionControllerLayoutMap = {
  86. "left": {
  87. "selectComponentId": "xr-standard-trigger",
  88. "components": {
  89. "xr-standard-trigger": {
  90. "type": "trigger",
  91. "gamepadIndices": {
  92. "button": 0
  93. },
  94. "rootNodeName": "xr_standard_trigger",
  95. "visualResponses": {
  96. }
  97. },
  98. "xr-standard-squeeze": {
  99. "type": "squeeze",
  100. "gamepadIndices": {
  101. "button": 1
  102. },
  103. "rootNodeName": "xr_standard_squeeze",
  104. "visualResponses": {
  105. }
  106. },
  107. "xr-standard-touchpad": {
  108. "type": "touchpad",
  109. "gamepadIndices": {
  110. "button": 2,
  111. "xAxis": 0,
  112. "yAxis": 1
  113. },
  114. "rootNodeName": "xr_standard_touchpad",
  115. "visualResponses": {
  116. },
  117. },
  118. "menu": {
  119. "type": "button",
  120. "gamepadIndices": {
  121. "button": 4
  122. },
  123. "rootNodeName": "menu",
  124. "visualResponses": {
  125. }
  126. }
  127. },
  128. "gamepadMapping": "xr-standard",
  129. "rootNodeName": "htc_vive_none",
  130. "assetPath": "none.glb"
  131. },
  132. "right": {
  133. "selectComponentId": "xr-standard-trigger",
  134. "components": {
  135. "xr-standard-trigger": {
  136. "type": "trigger",
  137. "gamepadIndices": {
  138. "button": 0
  139. },
  140. "rootNodeName": "xr_standard_trigger",
  141. "visualResponses": {
  142. }
  143. },
  144. "xr-standard-squeeze": {
  145. "type": "squeeze",
  146. "gamepadIndices": {
  147. "button": 1
  148. },
  149. "rootNodeName": "xr_standard_squeeze",
  150. "visualResponses": {
  151. }
  152. },
  153. "xr-standard-touchpad": {
  154. "type": "touchpad",
  155. "gamepadIndices": {
  156. "button": 2,
  157. "xAxis": 0,
  158. "yAxis": 1
  159. },
  160. "rootNodeName": "xr_standard_touchpad",
  161. "visualResponses": {
  162. },
  163. },
  164. "menu": {
  165. "type": "button",
  166. "gamepadIndices": {
  167. "button": 4
  168. },
  169. "rootNodeName": "menu",
  170. "visualResponses": {
  171. }
  172. }
  173. },
  174. "gamepadMapping": "xr-standard",
  175. "rootNodeName": "htc_vive_none",
  176. "assetPath": "none.glb"
  177. },
  178. "none": {
  179. "selectComponentId": "xr-standard-trigger",
  180. "components": {
  181. "xr-standard-trigger": {
  182. "type": "trigger",
  183. "gamepadIndices": {
  184. "button": 0
  185. },
  186. "rootNodeName": "xr_standard_trigger",
  187. "visualResponses": {
  188. }
  189. },
  190. "xr-standard-squeeze": {
  191. "type": "squeeze",
  192. "gamepadIndices": {
  193. "button": 1
  194. },
  195. "rootNodeName": "xr_standard_squeeze",
  196. "visualResponses": {
  197. }
  198. },
  199. "xr-standard-touchpad": {
  200. "type": "touchpad",
  201. "gamepadIndices": {
  202. "button": 2,
  203. "xAxis": 0,
  204. "yAxis": 1
  205. },
  206. "rootNodeName": "xr_standard_touchpad",
  207. "visualResponses": {
  208. },
  209. },
  210. "menu": {
  211. "type": "button",
  212. "gamepadIndices": {
  213. "button": 4
  214. },
  215. "rootNodeName": "menu",
  216. "visualResponses": {
  217. }
  218. }
  219. },
  220. "gamepadMapping": "xr-standard",
  221. "rootNodeName": "htc-vive-none",
  222. "assetPath": "none.glb"
  223. }
  224. };