index.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. Component({
  2. behaviors: [require('../common/share-behavior').default],
  3. properties: {
  4. },
  5. data: {
  6. loaded: false,
  7. arReady: false,
  8. },
  9. lifetimes: {
  10. detached() {
  11. wx.setKeepScreenOn({keepScreenOn: false});
  12. }
  13. },
  14. methods: {
  15. handleReady({detail}) {
  16. const xrScene = this.scene = detail.value;
  17. this.inRealWorld = true;
  18. console.log('xr-scene', xrScene);
  19. },
  20. handleAssetsProgress: function ({detail}) {
  21. console.log('assets progress', detail.value);
  22. },
  23. handleAssetsLoaded: function ({detail}) {
  24. console.log('assets loaded', detail.value);
  25. this.setData({loaded: true});
  26. this.scene.event.addOnce('touchstart', this.placeNode.bind(this));
  27. wx.showToast({title: '点击屏幕放置'});
  28. },
  29. handleTick() {
  30. if (!this.placed) {
  31. return;
  32. }
  33. const xrSystem = wx.getXrFrameSystem();
  34. const mainCamEl = this.scene.getElementById('main-camera');
  35. const magicCamEl = this.scene.getElementById('magic-camera');
  36. const mainTrs = mainCamEl.getComponent(xrSystem.Transform);
  37. const door = this.scene.getElementById('door').getComponent(xrSystem.Transform);
  38. let forward = door.worldForward;
  39. forward = xrSystem.Vector2.createFromNumber(forward.x, forward.z);
  40. let diff = mainTrs.worldPosition.sub(door.worldPosition);
  41. diff = xrSystem.Vector2.createFromNumber(diff.x, diff.z);
  42. const preDiff = this.diff || diff;
  43. this.diff = diff;
  44. const dis = diff.length();
  45. const preDis = preDiff.length();
  46. const dir = forward.dot(diff);
  47. //@todo: 等待物理加上碰撞检测,替换
  48. if (preDis <= 0.2 || dis > 0.2) {
  49. return;
  50. }
  51. if (this.inRealWorld && dir >= 0) {
  52. return;
  53. }
  54. if (!this.inRealWorld && dir <= 0) {
  55. return;
  56. }
  57. const mainCam = mainCamEl.getComponent(xrSystem.Camera);
  58. const magicCam = magicCamEl.getComponent(xrSystem.Camera);
  59. const doorMesh = this.scene.getElementById('door-mesh').getComponent(xrSystem.Mesh);
  60. const sceneMesh = this.scene.getElementById('scene-mesh').getComponent(xrSystem.GLTF);
  61. if (!this.inRealWorld) {
  62. // 现实世界
  63. // mainCam: ar -> stencil -> scene
  64. // magicCam: nothing
  65. this.inRealWorld = true;
  66. mainCam.setData({background: 'ar'});
  67. magicCam.setData({background: 'default'});
  68. magicCam.setData({isClearDepth: false});
  69. magicCam.clearBackgroundRenderStates();
  70. doorMesh.material.renderQueue = 1;
  71. doorMesh.material.setRenderState('cullFace', 2);
  72. sceneMesh.meshes.forEach(mesh => mesh.material.setRenderState('stencilComp', 3));
  73. } else {
  74. // 虚拟世界
  75. // mainCam: scene -> stencil
  76. // magicCam: ar
  77. this.inRealWorld = false;
  78. mainCam.setData({background: 'default'});
  79. magicCam.setData({background: 'ar'});
  80. magicCam.setData({isClearDepth: true});
  81. magicCam.setBackgroundRenderStates({
  82. stencilComp: 3,
  83. stencilRef: 1,
  84. stencilReadMask: 1
  85. });
  86. doorMesh.material.renderQueue = 9999;
  87. doorMesh.material.setRenderState('cullFace', 1);
  88. sceneMesh.meshes.forEach(mesh => mesh.material.setRenderState('stencilComp', 0));
  89. }
  90. },
  91. placeNode(event) {
  92. const {clientX, clientY} = event.touches[0];
  93. const {frameWidth: width, frameHeight: height} = this.scene;
  94. if (clientY / height > 0.8 && clientX / width > 0.8) {
  95. this.scene.getNodeById('setitem').visible = false;
  96. this.scene.ar.resetPlane();
  97. this.scene.event.addOnce('touchstart', this.placeNode.bind(this));
  98. } else {
  99. this.scene.ar.placeHere('setitem', true);
  100. this.scene.getElementById('anchor').getComponent(wx.getXrFrameSystem().Transform).setData({visible: false});
  101. this.placed = true;
  102. wx.setKeepScreenOn({keepScreenOn: true});
  103. }
  104. },
  105. }
  106. })