index.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. const SERVER_LOCALIZE = 'localize'
  2. const originalCanvas = wx.createOffscreenCanvas({type: '2d', width: 2, height: 2})
  3. const targetCanvas = wx.createOffscreenCanvas({type: '2d', width: 2, height: 2})
  4. const originalCtx = originalCanvas.getContext('2d')
  5. const targetCtx = targetCanvas.getContext('2d')
  6. let startTime = null
  7. let isLocalizing = false
  8. // components/xr-start/index.js
  9. Component({
  10. /**
  11. * Component properties
  12. */
  13. properties:
  14. {
  15. },
  16. /**
  17. * Component initial data
  18. */
  19. data:
  20. {
  21. loaded: false,
  22. arReady: false,
  23. // serverUrl: 'https://api.immersal.com',
  24. // developerToken: '<your token>',
  25. // mapIds: [88263]
  26. serverUrl: 'https://immersal.hexagon.com.cn',
  27. //developerToken: 'af9b02252f43f8843dbb7f78b5bd79a1a3d6ea872387057a2cd83646ade6e360',
  28. //mapIds: [1903]
  29. developerToken: 'aa484c64c5664ede765b54cc3ae6ba584924cd8d9b650678f7844139ecc79e2a',
  30. mapIds: [88985]
  31. },
  32. /**
  33. * Component methods
  34. */
  35. methods:
  36. {
  37. handleReady: function ({detail}) {
  38. this.scene = detail.value
  39. wx.showToast({title: 'Scene initialized!'})
  40. },
  41. handleAssetsLoaded: function({detail}) {
  42. this.setData({loaded: true})
  43. this.scene.event.add('touchstart', () => {
  44. this.prepareImageData()
  45. })
  46. },
  47. prepareImageData: async function() {
  48. if (isLocalizing)
  49. return
  50. isLocalizing = true
  51. const xrFrameSystem = wx.getXrFrameSystem()
  52. const arRawData = this.scene.ar.getARRawData()
  53. const viewMatrix = new (xrFrameSystem.Matrix4)(arRawData.viewMatrix)
  54. const trackerSpace = viewMatrix.inverse().clone()
  55. const intrinsics = {
  56. fx: arRawData.intrinsics[0],
  57. fy: arRawData.intrinsics[4],
  58. ox: arRawData.intrinsics[6],
  59. oy: arRawData.intrinsics[7]
  60. }
  61. this.localize(trackerSpace, arRawData.yBuffer, arRawData.width, arRawData.height, intrinsics)
  62. },
  63. localize: function(trackerSpace, image, width, height, intrinsics) {
  64. console.log('localization start')
  65. const that = this
  66. const xrFrameSystem = wx.getXrFrameSystem()
  67. const json = {token: this.data.developerToken, fx: intrinsics.fx, fy: intrinsics.fy, ox: intrinsics.ox, oy: intrinsics.oy, mapIds: this._formatMapIds()}
  68. const jsonStr = JSON.stringify(json)
  69. const jsonBytes = new Array(jsonStr.length)
  70. for (let i = 0; i < jsonStr.length; i++) {
  71. jsonBytes[i] = jsonStr.charCodeAt(i)
  72. }
  73. const imgHeader = 'P5\n# Created by Immersal\n' + width + ' ' + height + '\n255\n'
  74. const headerBytes = new Array(imgHeader.length)
  75. for (let i = 0; i < imgHeader.length; i++) {
  76. headerBytes[i] = imgHeader.charCodeAt(i)
  77. }
  78. const pgmBuffer = new ArrayBuffer(headerBytes.length + image.byteLength)
  79. const imgView = new Uint8Array(pgmBuffer)
  80. imgView.set(headerBytes, 0)
  81. imgView.set(new Uint8Array(image), headerBytes.length)
  82. const payload = new ArrayBuffer(jsonBytes.length + 1 + pgmBuffer.byteLength)
  83. const view = new Uint8Array(payload)
  84. view.set(jsonBytes, 0)
  85. view.set([0], jsonBytes.length)
  86. view.set(imgView, jsonBytes.length + 1)
  87. wx.request({
  88. url: this.data.serverUrl + '/' + SERVER_LOCALIZE,
  89. data: payload,
  90. method: 'POST',
  91. dataType: 'json',
  92. success: function(resp) {
  93. isLocalizing = false
  94. const data = resp.data
  95. wx.showToast({title: 'Localized: ' + JSON.stringify(data)})
  96. if (data.success) {
  97. const tex = that.scene.getNodeById('immersaltex')
  98. const immScene = that.scene.getNodeById('immersaltexScene')
  99. if (tex) {
  100. const cloudSpace = new (xrFrameSystem.Matrix4)()
  101. cloudSpace.setArray([
  102. data.r00, data.r10, data.r20, 0,
  103. -data.r01, -data.r11, -data.r21, 0,
  104. -data.r02, -data.r12, -data.r22, 0,
  105. data.px, data.py, data.pz, 1
  106. ])
  107. const cloudSpaceFinal = cloudSpace.zRotate(Math.PI/2)
  108. const m = trackerSpace.multiply(cloudSpaceFinal.inverse())
  109. let position = new (xrFrameSystem.Vector3)()
  110. let rotationM = new (xrFrameSystem.Matrix4)()
  111. let scale = new (xrFrameSystem.Vector3)()
  112. m.decomposeTransRotMatScale(position, rotationM, scale)
  113. const rotation = xrFrameSystem.Quaternion.createFromMatrix4(rotationM)
  114. tex.position.setValue(position.x, position.y, position.z)
  115. tex.quaternion.setValue(rotation.x, rotation.y, rotation.z, rotation.w)
  116. tex.scale.setValue(scale.x, scale.y, scale.z)
  117. immScene.position.setValue(position.x, position.y, position.z)
  118. immScene.quaternion.setValue(rotation.x, rotation.y, rotation.z, rotation.w)
  119. // immScene.scale.setValue(scale.x, scale.y, scale.z)
  120. }
  121. }
  122. },
  123. fail: function(error) {
  124. isLocalizing = false
  125. wx.showModal({
  126. title: 'Failed!',
  127. content: '' + error.errno + '\n' + error.errMsg
  128. })
  129. }
  130. })
  131. },
  132. _formatMapIds: function() {
  133. const n = this.data.mapIds.length
  134. const mapIdArray = [n]
  135. for (let i = 0; i < n; i++) {
  136. mapIdArray[i] = {id: this.data.mapIds[i]}
  137. }
  138. return mapIdArray
  139. }
  140. }
  141. })