123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- Component({
- behaviors: [require('../../common/share-behavior').default],
- innerInterval: 0,
- videoId: -1,
- properties: {
- markerListRaw: {
- type: Array,
- value: []
- },
- },
- data: {
- loaded: true,
- arReady: false,
- gltfLoaded: false,
- videoLoaded: false,
- videoRatioLoaded: false,
- markerWidth: 1,
- markerHeight: 1,
- },
- observers: {
- markerListRaw(newVal) {
- this.setData({
- markerList: newVal,
- })
- },
- },
- lifetimes: {
- detached() {
- // 关闭时候去除计时器
- clearInterval(this.innerInterval);
- }
- },
- methods: {
- handleReady({detail}) {
- const xrScene = this.scene = detail.value;
- console.log('xr-scene', xrScene);
- // 加载场景资源
- const gltfResList = [];
- const videoResList = [];
- const markerList = this.data.markerList;
- for(let i = 0; i < markerList.length; i++) {
- const marker = markerList[i];
- switch (marker.renderType) {
- case 'gltf':
- gltfResList.push(marker);
- break;
- case 'video':
- videoResList.push(marker);
- break;
- }
- }
- try {
- this.loadGLTF(gltfResList)
- } catch (err) {
- console.log('[gltf load] error: ', err)
- }
- },
- handleARReady: function() {
- console.log('arReady')
- this.setData({ arReady: true })
- },
- async loadGLTF(gltfList) {
- const scene = this.scene
- const gltfModel = await Promise.all(gltfList.map(gltfItem => scene.assets.loadAsset({
- type: 'gltf',
- assetId: 'gltf-' + gltfItem.id,
- src: gltfItem.src,
- })))
- console.log('glTF asset loaded')
- this.setData({ gltfLoaded: true })
- },
- async loadVideoSingle(videoItem) {
- const scene = this.scene
- const videoTexture = await scene.assets.loadAsset({
- type: 'video-texture',
- assetId: `video-` + videoItem.id,
- src: videoItem.src,
- options: { loop: true, autoPlay: true },
- });
- // console.log('videoTexture', videoTexture);
- const videoMat = scene.createMaterial(
- scene.assets.getAsset('effect', 'simple'),
- { u_baseColorMap: videoTexture.value.texture }
- )
- scene.assets.addAsset('material', `video-mat-${videoItem.id}`, videoMat)
- console.log('video asset loaded')
- this.setData({
- videoLoaded: true,
- })
- },
- releaseVideo(id) {
- if (id !== -1) {
- // 存在纹理才进行释放
- const scene = this.scene
- // 释放加载过的资源
- scene.assets.releaseAsset('video-texture', `video-${id}`);
- scene.assets.releaseAsset('material', `video-mat-${id}`);
- }
- },
- handleTrackerSwitch({ detail }) {
- console.log('tracked match')
- if (this.data.loaded) {
- const element = detail.el;
- const active = detail.value;
- const data = this.data;
- const markerList = data.markerList;
- for (let i = 0; i < markerList.length; i++) {
- const markerInfo = markerList[i];
- const markerTracker = this.scene.getElementById(`marker-${markerInfo.id}`)
- if (element === markerTracker) {
- // 处理视频纹理
- this.releaseVideo(this.videoId);
- this.videoId = -1;
- // 匹配 tracker
- switch (markerInfo.renderType) {
- case 'scan': // scan
- this.scanHandler(markerTracker, markerInfo, active);
- break;
- case 'video': // video
- if (active) {
- this.videoHanler(markerInfo);
- }
- break;
- case 'gltf': // gltf
- break;
- }
- this.triggerEvent('trackerchange', {
- name: markerInfo.name,
- active: active,
- type: markerInfo.renderType,
- })
- }
- }
- }
- },
- scanHandler(markerTracker, markerInfo, active) {
- const renderType = markerInfo.renderType
- const xrFrameSystem = wx.getXrFrameSystem()
- const camera = this.scene.getElementById('camera').getComponent(xrFrameSystem.Camera);
- const trackerTRS = markerTracker.getComponent(xrFrameSystem.Transform)
- const rightTRS = this.scene.getElementById(`normal-right-${markerInfo.id}`).getComponent(xrFrameSystem.Transform);
- const trackerPos = camera.convertWorldPositionToClip(trackerTRS.worldPosition)
- const rightPos = camera.convertWorldPositionToClip(rightTRS.worldPosition)
- const posX = ((trackerPos.x + 1) / 2)
- const posY = (1 - (trackerPos.y + 1) / 2)
- const rightPosX = ((rightPos.x + 1) / 2)
- // 获取识别图,图片比例
- let widthDivideHeight = 1
- wx.getImageInfo({
- src: markerInfo.markerImage,
- success: res => {
- const {
- width,
- height
- } = res
- widthDivideHeight = width / height
- },
- fail: res => {
- console.error(res)
- }
- })
- // 通知上层
- this.triggerEvent('trackerchange', {
- name: markerInfo.name,
- active: active,
- type: renderType,
- trackerInfo: {
- x: posX,
- y: posY,
- halfWidth: rightPosX - posX,
- widthDivideHeight
- }
- })
- if (active) {
- // 激活态开启tracker位置同步
- let preX = posX;
- let preY = posY;
- let preR = rightPosX
- this.innerInterval = setInterval(()=>{
- const tPos = camera.convertWorldPositionToClip(trackerTRS.worldPosition)
- const rPos = camera.convertWorldPositionToClip(rightTRS.worldPosition)
- const pX = ((tPos.x + 1) / 2)
- const pY = (1 - (tPos.y + 1) / 2)
- const rX = ((rPos.x + 1) / 2)
- const dX = Math.abs(pX - preX)
- const dY = Math.abs(pY - preY)
- const dR = Math.abs(rX - preR)
- if (dX > 0.005 || dY > 0.005 || dR > 0.005) {
- preX = pX;
- preY = pY;
- preR = rX
- this.triggerEvent('trackermove', {
- active: true,
- type: 'scan',
- trackerInfo: {
- x: pX,
- y: pY,
- halfWidth: rX - pX,
- widthDivideHeight
- }
- })
- }
- }, 40)
- } else {
- // 取消态去除tracker位置同步
- clearInterval(this.innerInterval)
- this.triggerEvent('trackermove', {
- active: false,
- type: 'scan',
- trackerInfo: {
- x: 0,
- y: 0,
- halfWidth: 0
- }
- })
- }
- },
- videoHanler(markerInfo) {
- this.setData({
- videoLoaded: false,
- videoRatioLoaded: false,
- })
- // 获取识别图,图片比例
- wx.getImageInfo({
- src: markerInfo.markerImage,
- success: res => {
- const {
- width,
- height
- } = res
- const widthDivideHeight = width / height;
- this.setData({
- markerWidth: 1,
- markerHeight: (1 / widthDivideHeight).toFixed(2),
- videoRatioLoaded: true,
- });
- },
- fail: res => {
- console.error(res)
- }
- })
- try {
- this.loadVideoSingle(markerInfo)
- } catch (err) {
- console.log('[video load] error: ', err)
- }
- this.videoId = markerInfo.id;
- }
- }
- })
|