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

news2024/11/25 1:07:23
  • 基础知识:

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
        });
    }
  }
})
  • 效果展示: 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++职工管理系统(类继承、文件、指针操作、中文乱码解决)

文件目录及界面 CMakeLists.txt避免中文乱码配置。 # C的解决办法 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fexec-charsetGBK") # C 的解决办法 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexec-charsetGBK") 一、退出管理程序 退出当前管理…

不需要#魔#法就能直接访问chatgpt

你还在付费使用chatgpt吗&#xff1f;你还在使用魔法访问chatgpt吗&#xff1f;你还在忍受每分钟刷新一下页面才能继续与gpt聊天吗&#xff1f; 今天给大家分享2种方法&#xff0c;可以使用国内网络在本地就能直接访问chatgpt。 这两种方法都是基于GitHub上的开源项目chatbot-u…

基于SSM的网上宠物店

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

低代码赋能生物药企数字化

一、关于复宏汉霖 汉霖是复星在2010年投资孵化的一家生物医药公司&#xff0c;经过这十几年的发展&#xff0c;2019年在港股上市&#xff0c;是生物药企18A企业之一。 经过这些年的发展&#xff0c;我们在管线方面布局了肿瘤、肢体、免疫、眼科类&#xff0c;从早研阶段到临床…

Midjourney|文心一格prompt教程[Text Prompt(下篇)]:游戏、实物、人物、风景、动漫、邮票、海报等生成,终极模板教学

Midjourney|文心一格prompt教程[Text Prompt&#xff08;下篇&#xff09;]&#xff1a;游戏、实物、人物、风景、动漫、邮票、海报等生成&#xff0c;终极模板教学 场景6&#xff1a;游戏 Prompt 真的越长越好吗&#xff1f; 按照 Midjourney 的官方文档里的说法&#xff0…

基于html+css的图展示76

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

人类禁止进入的“微博”,我的AI机器人在那里吹牛,“勾搭”AI小姑娘

最近球友推荐了一个非常有趣的网站&#xff0c;叫“奇鸟”&#xff08;https://chirper.ai/zh&#xff09;。 简单来说&#xff0c;这是一个AI专属的微博&#xff0c;人类禁止发言&#xff0c;但是你可以创建一个叫“奇鸟”的机器人代理&#xff0c;让它在里边发帖&#xff0c;…

扫眼球换“世界币” ChatGPT之父“剥削穷人”?

ChatGPT火爆全球后&#xff0c; 山姆奥特曼&#xff08;Sam Altman&#xff09;创立的加密项目Worldcoin&#xff08;世界币&#xff09;重回大众视野。这个项目诞生于2年前。那时&#xff0c;埋头迭代GPT模型的OpenAI还未如此知名&#xff0c;该公司的CEO 山姆奥特曼也位列科技…

【计算机视觉】CLIP实战:Zero-Shot Prediction(含源代码)

一、代码实战 下面的代码使用 CLIP 执行零样本预测。 此示例从 CIFAR-100 数据集中获取图像&#xff0c;并预测数据集中 100 个文本标签中最可能的标签。 import os import clip import torch from torchvision.datasets import CIFAR100# Load the model device "cuda…

Android Parceable 使用和原理

简介 在 Android 开发中&#xff0c;我们经常需要在不同的组件之间传递数据&#xff0c;比如在 Activity 之间传递数据、在 Service 和 Activity 之间传递数据等。为了实现数据的传递&#xff0c;Android 提供了两种常用的方式&#xff0c;一种是使用 Intent&#xff0c;另一种…

opencv_c++学习(十)

一、图像尺寸变化 图像插值原理 在图像变换的过程中往往需要对像素进行相关的操作。如上图&#xff08;左&#xff09;所示&#xff0c;我们会遇到两个相邻的像素块需要映射到同样的位置中&#xff0c;或者两个相邻的位置的像素中间需要映射出一个位置的像素块。这时候我们就需…

JavaEE(系列7) -- 多线程(wait 和 notify 的使用)

首先对上一章节的指令重排序,在进行解释一下; 假设现在有连个线程 t1 和 t2 t1频繁(速度特别快)读取主内存&#xff0c;效率比较低&#xff0c;就被优化成直接读自己的工作内存。 t2修改了主内存的结果&#xff0c;由于t1没有读主内存&#xff0c;导致修改不能被识别到。 1.什么…

全网最全最细的【设计模式】总目录,收藏起来慢慢啃,看完不懂砍我

文章目录 一、设计模式七大原则1、单一职责原则2、接口隔离原则3、依赖倒置原则4、里氏替换原则5、开闭原则6、迪米特法则7、合成复用原则 二、UML类图三、设计模式1、创建型模式&#xff08;1&#xff09;单例模式&#xff08;常用&#xff09;&#xff08;2&#xff09;原型模…

mybatis-config.xml文件中的mappers标签

前言 在MyBatis中&#xff0c;< mapper >标签非常重要&#xff0c;因为它对应着我们存放sql语句的xml文件&#xff0c;在之前的使用中我们都是使用resource来指定路径&#xff0c;但其实除了resource可以指定路径的还有url和class但路径形式有所不同&#xff0c;下面来讨…

用「明道云+ChatGPT+Weaviate」挑战零代码1小时实现ChatPDF

ChatGPT流行起来之后&#xff0c;快速的出现了一批基于ChatGPT的工具应用&#xff0c;ChatPDF就是其中比较受欢迎的一款。它是一个可以让你与PDF文件进行对话的工具&#xff0c;既可以帮助你快速提取PDF文件中的信息&#xff0c;例如手册、论文、合同、书籍等&#xff1b;也可以…

【计算机视觉】最后显示的CIFAR-100数据集照片很模糊怎么解决?

文章目录 一、前言二、如何解决2.1 使用图像增强技术2.2 使用插值方法2.3 使用更高分辨率的图像数据集2.4 手动调整图像尺寸 三、总结 一、前言 如果从CIFAR-100数据集加载的图像显示模糊&#xff0c;可能有几个可能的原因&#xff1a; 分辨率较低&#xff1a;CIFAR-100数据集…

全力押注预制菜,叮咚买菜或错失即时零售红利

实际上&#xff0c;叮咚买菜相比于美团、京东更适合抢分即时零售的市场红利。 目前美团进入即时零售的逻辑是&#xff0c;拥有几百万骑手的履约软硬件可以复用&#xff0c;同时从外卖场景延伸到其他消费场景比较丝滑&#xff0c;从平台几千万用户的温饱满足&#xff0c;延展到多…

计算机网络实验(ensp)-实验10:三层交换机实现VLAN间路由

目录 实验报告&#xff1a; 实验操作 1.建立网络拓扑图并开启设备 2.配置主机 1.打开PC机 配置IP地址和子网掩码 2.配置完成后点击“应用”退出 3.重复步骤1和2配置每台PC 3.配置交换机VLAN 1.点开交换机 2.输入命名&#xff1a;sys 从用户视图切换到系统视图…

网络工程师精选习题详解(一)

请点击↑关注、收藏&#xff0c;本博客免费为你获取精彩知识分享&#xff01;有惊喜哟&#xff01;&#xff01; 1.在IPv4地址192.168.2.0/24中&#xff0c;表示主机的二进制位数是&#xff08; &#xff09;位。 A.8 B.16 C.24 D.32 答案&#xff1a;A /24示网络…

面对职业焦虑,我们能做些什么?

目录 大环境分析&#xff1a;AI 发展汹涌而上温水煮青蛙&#xff1a;那些“被替代”的“我们”码农分类&#xff1a;程序员都在做些什么码农黑暗季&#xff1a;失业潮原因分析程序员短期真的可替代吗&#xff1f;AI 发展来势汹汹&#xff0c;如何顺势而为最后&#xff1a;纵观全…