Three.JS飞入定位模型的位置。

news2024/9/24 13:24:42

源码

  flyTo(object, gltfthis) {
    if (object === undefined || object === null) {
      return;
    }
    const box3 = new THREE.Box3();
    box3.expandByObject(object); // 计算模型包围盒
    const size = new THREE.Vector3();
    box3.getSize(size); // 计算包围盒尺寸
    const center = new THREE.Vector3();
    box3.getCenter(center); // 计算一个层级模型对应包围盒的几何体中心坐标

    function maxSize(vec3) {
      let max;
      if (vec3.x > vec3.y) {
        max = vec3.x;
      } else {
        max = vec3.y;
      }
      if (max < vec3.z) {
        max = vec3.z;
      }
      return max;
    }
    const max = maxSize(size); // 包围盒长宽高中最大的一个值,用来表征模型的尺寸
    var tmp = center.clone().addScalar(max);
    var newPos = new THREE.Vector3(tmp.x, tmp.y, tmp.z);
    newPos.y = newPos.y + 3.0;
    newPos.z = newPos.z + 2.0;
    var targetPos = new THREE.Vector3(center.x, center.y, center.z);
    targetPos.y = targetPos.y + 1;
    let tis = this;
    if (object.type == "Group") {
      tis = gltfthis;
    }
    tis.animateCameraFun(
      tis.camera.position,
      tis.controls.target,
      newPos,
      targetPos,
      2000
    );
  },
  1. 参数检查与初始化:

    • 首先检查传入的 object 是否为 undefined 或 null,如果是则直接返回,不执行后续的操作。 
  2. 计算包围盒和尺寸:

    • 使用 THREE.Box3 来计算传入对象 object 的包围盒 (box3)。
    • 通过 box3.getSize(size) 获取包围盒的尺寸 size
    • 使用 box3.getCenter(center) 获取包围盒的中心坐标 center。 
  3. 计算模型尺寸的最大值:

    • 定义了一个函数 maxSize(vec3),用来返回三维向量 vec3 中的最大值,即包围盒尺寸的长、宽、高中的最大值。 
  4. 计算新的相机位置 (newPos) 和目标位置 (targetPos):

    • 计算出最大尺寸 max,然后基于包围盒的中心 center 和最大尺寸 max 计算出新的相机位置 newPos,稍微偏移了一定的距离(y轴上+3.0,z轴上+2.0)。
    • 计算目标位置 targetPos,也稍作偏移(y轴上+1)。
  5. 动态设置 tis 对象:

    • 根据传入的 object 的类型,动态选择 tis 对象。如果 object.type 是 "Group",则将 tis 设置为 gltfthis,否则保持原先的 this
    • 如果是创建mesh不需要这部,因为我gitf模型的处理是用回调去处理添加的gltb模型。so需要手动传入this。
  6. 调用相机动画函数:

    • 最后调用 tis.animateCameraFun() 方法,传入相机位置 (tis.camera.position)、控制器的目标位置 (tis.controls.target)、新的相机位置 (newPos)、目标位置 (targetPos),以及动画持续的时间(2000毫秒)。

动画源码

  /**
   *
   * @param {*} oldPos 原来相机位置
   * @param {*} oldTarget  原来controls
   * @param {*} newPos new相机位置
   * @param {*} newTarget   new controls
   * @param {*} time
   */
  animateCameraFun(oldPos, oldTarget, newPos, newTarget, time) {
    const that = this;
    if (time === undefined || time === null) {
      time = 1000;
    }
    // 使用tween动画
    var tween = new TWEEN.Tween({
      x1: oldPos.x, // 相机x
      y1: oldPos.y, // 相机y
      z1: oldPos.z, // 相机z
      x2: oldTarget.x, // 控制点的中心点x
      y2: oldTarget.y, // 控制点的中心点y
      z2: oldTarget.z, // 控制点的中心点z
    });
    tween.to(
      {
        x1: newPos.x,
        y1: newPos.y,
        z1: newPos.z,
        x2: newTarget.x,
        y2: newTarget.y,
        z2: newTarget.z,
      },
      time
    );
    tween.easing(TWEEN.Easing.Cubic.InOut);
    tween.onUpdate(function (pos) {
      // that.renderScene2();
      that.camera.position.x = pos.x1;
      that.camera.position.y = pos.y1;
      that.camera.position.z = pos.z1;
      that.controls.target.x = pos.x2;
      that.controls.target.y = pos.y2;
      that.controls.target.z = pos.z2;
      that.camera.updateProjectionMatrix(); // 渲染范围改变,注意更新投影矩阵
      that.controls.update();
    });
    tween.onComplete(function () {
      that.controls.update();
    });
    // 开始动画
    tween.start();
  },

 函数定义animateCameraFun 是一个函数,接受旧的相机位置 (oldPos) 和目标点 (oldTarget),以及新的相机位置 (newPos) 和目标点 (newTarget),还有一个可选的动画时间参数 (time)。

Tween 动画设置:使用 tween.js 库创建动画效果,实现平滑过渡。

这里创建了一个 Tween 对象,定义了初始状态(旧的相机位置和目标点)和最终状态(新的相机位置和目标点),以及动画的时间参数。

Tween 设置目标:通过 tween.to() 方法设置 Tween 的目标状态和动画时间。

缓动函数:使用 tween.easing() 方法设置缓动函数,这里使用了 TWEEN.Easing.Cubic.InOut,表示缓入缓出的三次方缓动效果。

Tween 更新和完成时的操作

  • tween.onUpdate() 方法在 Tween 更新时执行,更新相机和控制器的位置和目标点,并更新投影矩阵。
  • tween.onComplete() 方法在 Tween 完成时执行,确保最后一次更新控制器的状态。

启动动画:最后调用 tween.start() 开始动画效果。 

关键的地方:在render循环里面记得加  TWEEN.update();

 

???????????????????

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

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

相关文章

【stm32项目】基于stm32智能宠物喂养(完整工程资料源码)

基于STM32宠物喂养系统 前言&#xff1a; 随着人们生活幸福指数的提高&#xff0c;越来越多的家庭选择养宠物来为生活增添乐趣。然而&#xff0c;由于工作等原因&#xff0c;许多主人无法及时为宠物提供充足的食物与水。为了解决这一问题&#xff0c;我设计了一款便捷的宠物喂…

如何搭建一个RADIUS服务器?

1. 系统环境 1.1.操作系统 Ubuntu-20.04.1 &#xff08;kernel: 5.15.0-58-generic&#xff09; 1.2.所需软件 FreeRADIUS MariaDB 1.3.注意事项 本文提到的所有操作&#xff0c;都是以root 身份执行&#xff1b; 2. FreeRADIUS的安装 2.1. 安装FreeRADIUS服务器程序 以…

fMATLAB中fill函数填充不同区域

只需获取填充区域的边缘信息&#xff0c;函数边缘越详细越好&#xff0c;然后调用fill函数。 fill函数能够根据指定的顶点坐标和填充颜色来绘制多边形或曲线形状&#xff0c;并在其内部填充指定的颜色。这使得在MATLAB中创建具有视觉吸引力的图形变得简单而高效。 fill函数的…

TCP滑动窗口和流量控制详解

1. 什么是滑动窗口 TCP 每发送⼀个数据&#xff0c;都需要⼀次应答&#xff0c;然后继续发送&#xff0c;这样为每个数据包都进⾏确认应答&#xff0c;缺点是&#xff1a;数据往返时间越⻓&#xff0c;⽹络吞吐量越低。为了解决这个问题&#xff0c;TCP 引⼊了 窗⼝ 这个概念。…

MISRA C2012学习笔记(7)-Rules 8.12

文章目录 8.12 表达式(Expressions)Rule 12.1 表达式中运算符的优先级应明确Rule 12.2 移位运算符的右操作数应在零到比左操作数基本类型的位宽度小一的范围内Rule 12.3 不得使用逗号(,)运算符Rule 12.4 常量表达式的求值不应导致无符号整数的回绕 8.12 表达式(Expressions) R…

Netty技术全解析:EventLoopGroup类详解

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

VBA技术资料MF174:利用文本框和列表框录入数据

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

Ubuntu网络连接图标消失了,没网!!!

文章目录 前言Step1&#xff1a;停止网络管理服务Step2&#xff1a;删除网络管理状态文件Step3&#xff1a;打开网络管理 前言 本次记录的事&#xff0c;有一天心血来潮想烧录一下开发板&#xff0c;却发现自己的Ubuntu系统的网络连接图标消失了&#xff0c;也没网了&#xff…

DEBUG:inpyb无法引用本地的py文件

问题 无法import 解决 暂时合并为一个文件 直接执行且测试简单模块可以引用&#xff08;部分复杂文件无法引用&#xff09;结合本程序 应该需要修改不规则的正则表达式 发现部分警告导致程序无法引用&#xff08;而且和环境有关 linux不会&#xff09;

医联体信息平台建设方案PPT(54页)

文章摘要&#xff1a; 医联体信息平台现状当前医联体信息平台存在脱离医疗业务建设的倾向&#xff0c;导致信息孤岛&#xff0c;业务协同困难。 建设存在的问题主要问题包括健康档案无法动态更新和共享&#xff0c;信息系统之间信息共享和协同不足。 医联体信息平台建设方案方…

【Linux】进程间通信及管道详细介绍(上)

前言 本节我们开始学习进程间通信相关的知识&#xff0c;并详细探讨一下管道&#xff0c;学习匿名管道和命名管道的原理和代码实现等相关操作… 目录 1. 进程间通信背景1.1 进程通信的目的&#xff1a; 2 管道的引入&#xff1a;2.1 匿名管道&#xff1a;2.1.1 匿名管道的原理&…

LATEX模板支持中文、目录和段落

\documentclass{ctexart} \usepackage{amsmath,amssymb,amsfonts,hyperref} \usepackage{CJKutf8} \usepackage{enumitem} % 引入宏包 \usepackage [colorlinkstrue] {} \begin{document}\begin{CJK}{UTF8}{gkai}%正文放在此行下与\end{CJK}之间就行\tableofcontents\newpage\s…

【Python】从基础到进阶(四):深入了解Python中的控制流

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、引言二、条件语句1. if 语句2. if-else 语句3. if-elif-else 语句4. 嵌套条件语句5. 三元运算符 三、循环语句1. for 循环基本语法使用range() 函数遍历列表、字典和字符串 2. while 循环基本语法无限循环与终止条件 3.…

Python 实现股票指标计算——BBI

BBI (Bull And Bear lndex) - 多空指标 1 公式 3日均价 3日收盘价之和 / 36日均价 6日收盘价之和 / 612日均价 12日收盘价之和 / 1224日均价 24日收盘价之和 / 24BBI (3日均价 6日均价 12日均价 24日均价) / 4 2 数据准备 我们以科创50指数 000688 为例&#xff0c…

使用Vue实现点击页面触发特效

效果描述 在页面上的指定区域内进行点击&#xff0c;则会在页面上显示设置好的随机文本&#xff0c;此文本出现后会执行动画&#xff0c;动画效果为节点在1s之内向右上方移动并在移动的过程中完成180翻转&#xff0c;最后消失。 效果展示 完整代码 <template><div…

Windows 11 Visual Studio 2022 cmake 3.29 CUDA12.5 构建VTK

The Visualization Toolkit (VTK)是一个用于操作和展示科学数据的开源软件&#xff0c;包括了二三维渲染功能。 下载VTK 从官网Download | VTK下载VTK版本&#xff0c;我下载的是9.3.1源代码&#xff0c;在Windows 11上安装。 CMake构建VTK的VS2022工程 生成与安装 分别生成De…

AI智能名片小程序:跨界融合,重塑品牌与顾客的“三度情缘”

在这个信息爆炸、竞争白热化的时代&#xff0c;品牌如何突破重围&#xff0c;与顾客建立超越常规的情感链接&#xff1f;答案或许就藏在那个看似不起眼&#xff0c;实则暗藏玄机的AI智能名片小程序里&#xff01;它不仅是技术的结晶&#xff0c;更是品牌与顾客之间“三度情缘”…

Redis持久化(AOF和RDB)

目录 前言 一.RDB 1.1手动执行 1.2自动执行 二.AOF 2.1重写机制 三.混合持久化 Redis的学习专栏&#xff1a;http://t.csdnimg.cn/a8cvV 前言 持久化&#xff0c;在之前&#xff0c;我们接触这个词汇是在mysql数据库当中的事务四大特性里。 持久性&#xff1a;指一旦事…

探索免费隧道服务:为本地开发提供自定义子域名的解决方案

目录 引言 使用Ngrok进行本地开发 免费替代方案 Localtunnel Serveo Ngrok付费计划&#xff08;有限的免费试用&#xff09; 开源替代方案 SISH 总结 引言 在Web开发中&#xff0c;将本地服务器暴露给互联网进行测试或演示是常见需求。Ngrok等工具因其便捷性而广受欢迎…

【LeetCode】分隔链表

目录 一、题目二、解法完整代码 一、题目 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 示例 1&#xff1a; 输入&a…