微信小程序xr-frame实现交互(地月案例)

  • 基础知识:

1.轮廓

  • 如果想要与场景中的物体进行互动,比如说点击、拖拽物体,那么这个物体得先拥有一个轮廓才行。
  • 轮廓是一个组件。与某个物体互动,实际上是在与这个物体的轮廓进行互动,轮廓让这个物体在物理世界中拥有了一个分身。
名称标签属性名组件数据备注
球状轮廓sphere-shapecenter, radius, autoFit
胶囊体轮廓capsule-shapecenter, radius, height, autoFit
长方体轮廓cube-shapecenter, size, autoFit
网格模型轮廓mesh-shape-自动适配元素下的Mesh和GLTF模型

2.创建轮廓

  • 创建轮廓非常简单,只要为xml标签添加上xxx-shape的属性即可。

例如:一个球体创建了一个球状轮廓

<xr-mesh node-id="mesh-sphere" geometry="sphere" sphere-shape></xr-mesh>

 注:任意一个场景标签都可以创建轮廓

3.轮廓交互

事件名描述事件的回调函数备注
touch-shape点击轮廓时触发IShapeTouchEvent如果有多个物体叠在一起,会点中最上层的。
drag-shape点击轮廓后,手指不松开的情况下进行拖拽时触发IShapeDragEvent只有在先触发touch-shape之后才会触发这个事件,target和touch-shape保持一致
untouch-shape点击轮廓后,手指松开时触发IShapeTouchEvent只有在先触发touch-shape之后才会触发这个事件。

整体代码以及效果:(来源于微信开放文档demo)

  • wxml部分
<xr-scene id="xr-scene" bind:tick="handleTick" bind:ready="handleReady">
  <xr-assets bind:progress="handleAssetsProgress" bind:loaded="handleAssetsLoaded">
    <xr-asset-load type="texture" asset-id="earth-texture" src="https://mmbizwxaminiprogram-1258344707.cos.ap-guangzhou.myqcloud.com/xr-frame/demo/2k_earth_daymap.jpeg" />
    <xr-asset-load type="texture" asset-id="moon-texture" src="https://mmbizwxaminiprogram-1258344707.cos.ap-guangzhou.myqcloud.com/xr-frame/demo/2k_moon.jpeg" />
    <xr-asset-load type="texture" asset-id="sky" src="https://mmbizwxaminiprogram-1258344707.cos.ap-guangzhou.myqcloud.com/xr-frame/demo/dark-cosmos.jpg" />
    <xr-asset-material asset-id="standard-mat" effect="standard" />
    <xr-asset-material asset-id="earth-mat" effect="standard" uniforms="u_baseColorMap: earth-texture" render-queue="501"/>
    <xr-asset-material asset-id="earth-silhouette" effect="simple" uniforms="u_baseColorFactor: 1.0 0.5 0 1.0" states="depthTestWrite: false" render-queue="500"/>
    <xr-asset-material asset-id="moon-mat" effect="standard" uniforms="u_baseColorMap: moon-texture" render-queue="503"/>
    <xr-asset-material asset-id="moon-silhouette" effect="simple" uniforms="u_baseColorFactor: 0.476 0.82 0.957 1.0" states="depthTestWrite: false" render-queue="502"/>
  </xr-assets>
  <xr-env sky-map="sky" is-sky2d/>
  <xr-node>
    <xr-mesh node-id="mesh-earth" position="0 0 0" scale="8 8 8" geometry="sphere" material="earth-mat" bind:touch-shape="handleTouchEarth" bind:untouch-shape="handleUntouchEarth" bind:drag-shape="handleEarthRotation" sphere-shape receive-shadow cast-shadow></xr-mesh>
    <xr-mesh node-id="earth-silhouette" scale="8.15 8.15 8.15" geometry="sphere" material="earth-silhouette" visible="{{touchingEarth}}"></xr-mesh>
    <xr-mesh node-id="mesh-moon" position="10 0 0" scale="1.5 1.5 1.5" rotation="0 90 0" geometry="sphere" material="moon-mat" bind:drag-shape="handleDragMoon" bind:touch-shape="handleTouchMoon" bind:untouch-shape="handleUntouchMoon" sphere-shape="radius: 1.5" receive-shadow cast-shadow>
    <xr-mesh node-id="moon-silhouette" scale="1.1 1.1 1.1" geometry="sphere" material="moon-silhouette" visible="{{touchingMoon}}"></xr-mesh>
    </xr-mesh>
    <xr-camera
      id="camera" node-id="camera" position="0 20 -35" clear-color="0 0 0 1"
      target="mesh-earth"
      background="skybox"
    ></xr-camera>
  </xr-node>
  <xr-node node-id="lights">
    <xr-light type="ambient" color="1 1 1" intensity="0.1" />
    <xr-light id="directional-light" type="directional" rotation="0 60 0" color="1 1 1" intensity="5"  shadow-distance="40" cast-shadow shadow-bias="0.004"/>
  </xr-node>
</xr-scene>
  • js部分
Component({
  properties: {
    a: Number,
  },
  data: {
    loaded: false,
    touchingMoon: false,
    touchingEarth: false,
    θ: Math.PI,
    r: 10,
    ω: 5e-4,
    outerRing: 20,
    innerRing: 10
  },
  lifetimes: {},
  methods: {
    handleReady({detail}) {
      const xrScene = this.scene = detail.value;
      console.log('xr-scene', xrScene);
    },
    handleAssetsProgress: function({detail}) {
      console.log('assets progress', detail.value);
    },
    handleAssetsLoaded: function({detail}) {
      console.log('assets loaded', detail.value);
      this.setData({loaded: true});
    },
    handleTouchEarth: function() {
      this.setData({
        touchingEarth: true
      });
    },
    handleUntouchEarth: function() {
      this.setData({
        touchingEarth: false
      });
    },
    handleEarthRotation: function({detail}) {
        const { target, deltaX } = detail.value;
        target._components.transform.rotation.y += deltaX / 100;
    },
    handleDragMoon: function({detail}) {
        const { dir, target, camera } = detail.value;
        const cameraPos = camera.el._components.transform.worldPosition;
        const k = -cameraPos.y / dir[1];
        const x = cameraPos.x + k * dir[0];
        const z = cameraPos.z + k * dir[2];
        const len = Math.sqrt(x * x + z * z);
        if (len > this.data.innerRing) {
            const transform = target._components.transform;
            const scale = len > this.data.outerRing ? this.data.outerRing / len : 1.0;
            transform.position.x = x * scale;
            transform.position.z = z * scale;
        }
    },
    handleTouchMoon: function() {
        this.setData({touchingMoon: true});
    },
    handleUntouchMoon: function() {
        const moon = this.scene.getNodeById("mesh-moon");
        const transform = moon.el._components.transform;
        const x = transform.position.x;
        const z = transform.position.z;
        const len = Math.sqrt(x * x + z * z);
        this.setData({
            r: len,
            θ: x < 0 ? Math.atan(z / x) + Math.PI : Math.atan(z / x),
            ω: Math.sqrt(2.5e-4 / (len * len * len))
        });
        this.setData({touchingMoon: false});
    },
    handleTick: function({detail}) {
        if (this.data.touchingMoon || !this.scene) return;
        const deltaTime = detail.value;
        const moon = this.scene.getNodeById("mesh-moon");
        const transform = moon.el._components.transform;
        const x = Math.cos(this.data.θ) * this.data.r;
        const z = Math.sin(this.data.θ) * this.data.r;
        transform.position.x = x;
        transform.position.z = z;
        transform.rotation.y -= this.data.ω * deltaTime;
        this.setData({
            θ: this.data.θ + this.data.ω * deltaTime
        });
    }
  }
})
  • 效果展示: 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/21616.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WordPress 如何开启多站点 含Apache和Nginx伪静态规则

WordPress 3.0以上的版本支持直接开启多站点模式,这样一来,你可以在一个后台切换多个站点进行管理。 最近打算折腾一个主题演示站,给每个主题使用独立的子站点来搭建演示,如果是Apache环境,配置就比较容易,但是倡萌使用的是 Nginx,花了大量的时间测试了N多网络上的伪静…

Weblogic SSRF 漏洞(CVE-2014-4210)

SSRF漏洞 ​ SSRF&#xff08;服务端请求伪造&#xff09;&#xff0c;指的是攻击者在未能取得服务器所有权限时&#xff0c;利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网。SSRF攻击通常针对外部网络无法直接访问的内部系统。 ​ 简单的说就是利用一个可…

Jenkins的持续集成与持续部署

系统总体架构 Gitlab Gitlab是一款主要用于代码管理的工具&#xff0c;相较于GitHub&#xff0c;可以自己搭建服务器&#xff0c;这可以避免因为网络速度慢导致部署效率低下&#xff0c;同时&#xff0c;自己搭建服务器&#xff0c;安全性更高。Jenkins Jenkins主要用于管理版本…

国内免费版ChatGPT

目录 前言&#xff1a;网站大全 1. ChatGPT是什么 2. ChatGPT的发展历程 3. ChatGPT对程序员的影响 4. ChatGPT对普通人的影响 5. ChatGPT的不足之处 前言&#xff1a;网站大全 AI文本工具站 (laicj.cn) ——gpt-3.5 功能强大(推荐&#xff09; Chatgpt在线网页版-…

Compose For Desktop 实践:使用 Compose-jb 做一个时间水印助手

前言 在我之前的文章 在安卓中实现读取Exif获取照片拍摄日期后以水印文字形式添加到照片上 中&#xff0c;我们已经实现了在安卓端读取 Exif 信息后添加文字水印到图片上。 也正如我在这篇文章中所说的&#xff0c;其实这个需求使用手机来实现是非常不合理的&#xff0c;一般…

jenkins入门与安装

一、实验环境 selinux iptables off 主机名IP系统版本gitlab10.10.10.200rhel7.5jenkins10.10.10.10rhel7.5tomcat10.10.10.11rhel7.5 二、安装jenkins 1、解压安装包 下载地址&#xff1a;https://download.docker.com/linux/static/stable/x86_64/ [rootjenkins ~]# tar xf …

视频截取动图怎么做?分享在线视频转gif小窍门

如何将一段视频制作成gif动图表情包呢&#xff1f;Gif表情包常见的制作方法就是将电影、电视剧中的某个画面截取出来做成gif表情包。那么&#xff0c;如何从视频中截取GIF呢&#xff1f; 一、怎样才能完成视频转gif制作&#xff1f; 通过使用GIF中文网的视频转gif&#xff08…

RT-Thread 1. GD32移植RT-Thread Nano

1. RT-Thread Nano 下载 RT-Thread Nano 是一个极简版的硬实时内核&#xff0c;它是由 C 语言开发&#xff0c;采用面向对象的编程思维&#xff0c;具有良好的代码风格&#xff0c;是一款可裁剪的、抢占式实时多任务的 RTOS。其内存资源占用极小&#xff0c;功能包括任务处理…

多维时序 | MATLAB实现CNN-BiGRU卷积神经网络结合双向门控循环单元多变量时间序列预测

多维时序 | MATLAB实现CNN-BiGRU卷积神经网络结合双向门控循环单元多变量时间序列预测 目录 多维时序 | MATLAB实现CNN-BiGRU卷积神经网络结合双向门控循环单元多变量时间序列预测预测结果基本介绍模型特点程序设计学习总结参考资料 预测结果 基本介绍 多维时序 | MATLAB实现CN…

字符串String

目录 String 字符串比较 charAt 取数组中的值 案例 substring 案例&#xff1a;手机号加密​ StringBuilder StringBuilder提高效率原理图 StringJoiner 字符串拼接底层方法 String 创造方法 直接赋值通过new关键字 / 构造方法 字符串比较 equals &#xff1a;要求比…

小白安装 stabel diffusion 篇

windows 系统安装 stabel diffusion 软件的方法其实很简单&#xff0c;只有 4 步&#xff08;安装过程遇到的报错问题&#xff0c;本文有详细的解决方案&#xff0c;都是我踩过的坑&#xff0c;给大家探路了&#xff09;&#xff1a; 1、安装 python&#xff08;建议安装 3.10…

Spark 2:Spark Core RDD算子

RDD定义 RDD&#xff08;Resilient Distributed Dataset&#xff09;叫做弹性分布式数据集&#xff0c;是Spark中最基本的数据抽象&#xff0c;代表一个不可变、可分区、里面的元素可并行计算的集合。 Resilient&#xff1a;RDD中的数据可以存储在内存中或者磁盘中。 Distribut…

玩客云刷NAS

测试路由器支持IPV6 参考 这里 我用的是TPlink WDR7660 支持IPV6 主要设置桥模式 玩客云刷写固件 参考 这里 还有这里 玩客云固定IP 参考这里 sudo armbian-config 选择Network 选择有线网络->ip 选择static 然后根据自己情况进行设置 点击OK即可 更新国内源 参考这里 证书…

Flowable 生成的表都是干嘛的?(一)

一.简介 Flowable 默认一共生成了 79 张数据表&#xff0c;了解这些数据表&#xff0c;有助于我们更好的理解 Flowable 中的各种 API。 接下来我们就对这 79 张表进行一个简单的分类整理。 ACT_APP_*&#xff08;5&#xff09;ACT_CMMN_*&#xff08;12&#xff09;ACT_CO_*…

rtl仿真器-epicsim安装和测试

前言 epicsim 是芯华章的仿真器&#xff0c;基于iverilog 据说速度快两倍。 源码 github https://github.com/x-epic/EpicSim gittee https://gitee.com/x-epic/ 公司网站 https://www.x-epic.com/index.html#/en/developer 维护中了 安装 依赖 有些 apt-get install 就可…

大量名片图片转excel表格文件怎么转?有什么好办法?

随着市场经济的发展和社交交往的频繁&#xff0c;名片作为有效沟通方式&#xff0c;优雅和高效地传递个人或公司信息的同时&#xff0c;时常成为人们忙碌生活的问题之一&#xff1a;对于一个拿到的名片&#xff0c;我们需要将它收藏或转录至手机、电脑等媒介记录&#xff0c;但…

Kali-linux使用假冒令牌

使用假冒令牌可以假冒一个网络中的另一个用户进行各种操作&#xff0c;如提升用户权限、创建用户和组等。令牌包括登录会话的安全信息&#xff0c;如用户身份识别、用户组和用户权限。当一个用户登录Windows系统时&#xff0c;它被给定一个访问令牌作为它认证会话的一部分。例如…

谈谈包装类与泛型

目录 包装类 基本数据类型与对应的包装类 装箱和拆箱 装箱 拆箱 泛型 什么是泛型 泛型的语法与使用 泛型的编译 擦除机制 泛型的上界 泛型方法 提到泛型的话&#xff0c;我们就先提一下包装类吧&#xff01; 包装类 在Java中&#xff0c;由于基本类型不是继承自Ob…

Linux内核(十五)sysrq 详解 II —— 代码框架详解

文章目录 sysrq模块初始化流程图sysrq模块代码详解sysrq产生kernel crash事件流程sysrq 整体框架图sysrq 框架中添加自定义实例 Linux 版本&#xff1a;Linux version 3.18.24 sysrq模块初始化流程图 sysrq模块源码路径&#xff1a;linux-3.18.24.x/drivers/tty/sysrq.c 编译…

C++控制台打飞机小游戏

我终于决定还是把这个放出来。 视频在这&#xff1a;https://v.youku.com/v_show/id_XNDQxMTQwNDA3Mg.html 具体信息主界面上都有写。 按空格暂停&#xff0c;建议暂停后再升级属性。 记录最高分的文件进行了加密。 有boss&#xff08;上面视频2分47秒&#xff09;。 挺好…