threejs全景图和锚点编辑的实现方案

目录
  • 全景图和锚点编辑
  • 全景图
    • 全景图拆解
  • 场景编辑方案
    • transformControls
    • 初始化控制器
    • 添加可移动对象
    • 平移、缩放、旋转
    • 保存对象
  • 结语

全景图和锚点编辑

今天来简单聊聊threejs全景图和锚点编辑的方案。 全景图也就是所谓的天空盒子,所应用到的场景例如:场景模型的天空背景、夜晚的星空背景、VR看房等~

锚点编辑这篇重点讲一讲锚点编辑,也就是所谓场景编辑的方案。其中思想无限接近于Low Code,说到Low Code!我拖更了四篇文章,由于过年那段时间太忙了,实在是没时间更新!看到许多人都在等我完事,感到十分抱歉,后续一定会整理好更新!

全景图

其实全景图没什么内容。可以想象成一个非常大正方体的盒子,通过六个面的图片衔接而成。而我们相机则是存在于正方体内部,这样就能形成一个视觉误差,认为我们处于场景中。

全景图拆解

以下就是全景图正方体拆解图,六个面互相衔接,可以脑补下当将这个正方体组装后,我们所看到就是一个无缝衔接的一个场景,当然认真看还是可以看出正方体的边界处。

可以把骰子脑补成相机所在的位置,这样就很容易理解

既然有天空盒子,那多个场景的天空盒子肯定存在不同之处。在我们切换场景如何切换对应的天空盒子呢?很简单,我们只需封装一个切换函数如下

// 添加地面和天空盒
Viewer.prototype.changeSkyBox = function (skydir) {
  const that = this
  // 创建几何模型 BoxGeometry('x轴', '轴', 'z轴')
  const geometry = new THREE.BoxGeometry(999, 999, 999)
  // 创建纹理贴图  前后  上下  左右
  const texture0 = new THREE.TextureLoader().load((gAppPath + `/images/ysThree/sky/${skydir}/px.jpg`))
  const texture1 = new THREE.TextureLoader().load((gAppPath + `/images/ysThree/sky/${skydir}/nx.jpg`))
  const texture2 = new THREE.TextureLoader().load((gAppPath + `/images/ysThree/sky/${skydir}/py.jpg`))
  const texture3 = new THREE.TextureLoader().load((gAppPath + `/images/ysThree/sky/${skydir}/ny.jpg`))
  const texture4 = new THREE.TextureLoader().load((gAppPath + `/images/ysThree/sky/${skydir}/pz.jpg`))
  const texture5 = new THREE.TextureLoader().load((gAppPath + `/images/ysThree/sky/${skydir}/nz.jpg`))
  // 添加材质
  const material = [
    new THREE.MeshBasicMaterial({color: 0xffddff, map: texture0, side: THREE.DoubleSide}),
    new THREE.MeshBasicMaterial({color: 0xffddff, map: texture1, side: THREE.DoubleSide}),
    new THREE.MeshBasicMaterial({color: 0xffddff, map: texture2, side: THREE.DoubleSide}),
    new THREE.MeshBasicMaterial({color: 0xffddff, map: texture3, side: THREE.DoubleSide}),
    new THREE.MeshBasicMaterial({color: 0xffddff, map: texture4, side: THREE.DoubleSide}),
    new THREE.MeshBasicMaterial({color: 0xffddff, map: texture5, side: THREE.DoubleSide})
  ]
  // 创建网格对象
  const cube = new _3d.Mesh(geometry, material)
  cube.layers.enableAll()
  cube.name = 'skybox'
  that.skybox && this.scene.remove(that.skybox)
  that.skybox = cube
  that.AmbientGroup.add(cube)
}

场景编辑方案

不同场景的灯光位置以及图标点位可能不同,作为一个基础编辑平台,我们肯定要考虑如何将我们的场景变成可配置化,根据不同的需求做出不同的改变。之前的文章介绍过我们将模型通过JSON的形式去配置,那我们如何将场景中的点位以及灯光位置做出配置呢?

transformControls

变换控制器,这里它的作用主要是对锚点的平移、缩放、旋转操作

初始化控制器

//移动控制器
this.transformControls = new TransformControls(this.camera, this.renderer.domElement)
this.transformControls.setSize(0.5)
this.scene.add(this.transformControls) //添加入场景

添加可移动对象

我们可以在比如说灯光类中,添加一个transform_attach方法,在启用编辑后调用该方法。只有attach后才能够被拾取,进行平移、旋转、缩放的操作

transformControls.attach(...)
//对象类中
transform_attach(value){
  if (value) {
    this.transformControls.attach(this.dlight)
  }
  else {
    this.transformControls.detach(this.dlight)
  }
}

平移、缩放、旋转

gapp.history.execute 这里主要是业务逻辑,将编辑后的对象保存起来,主要用于回显

SetPositionCommand 这里主要的作用是记录下旧的位置信息与新的位置信息

抛开上面两个方法,其实只要添加进变换控制器就可以对物体就行操作了,下面我单独介绍为什么需要保存信息

Viewer.prototype.bindTransformEvent = function () {

  this.transformControls.addEventListener('mouseDown', () => { //鼠标拾取到
    var object = gapp.transformControls.object //获取拾取对象
    this.objectPositionOnDown = object.position.clone()//保存位置
    this.objectRotationOnDown = object.rotation.clone()//保存角度
    this.objectScaleOnDown = object.scale.clone()//保存缩放大小
    gapp.controls.enabled = false
  })
  this.transformControls.addEventListener('mouseUp', () => {//鼠标提起
    var object = gapp.transformControls.object//获取拾取对象
    if (object !== undefined) {
      switch (gapp.transformControls.getMode()) { //这里判断是要进行平移、缩放、旋转操作
        case 'translate':
          if (!this.objectPositionOnDown.equals(object.position)) {
            gapp.history.execute(new SetPositionCommand(this, object, object.position, this.objectPositionOnDown))
          }
          break
        case 'rotate':
          if (!this.objectRotationOnDown.equals(object.rotation)) {
            gapp.history.execute(new SetRotationCommand(this, object, object.rotation, this.objectRotationOnDown))
          }
          break
        case 'scale':
          if (!this.objectScaleOnDown.equals(object.scale)) {
            gapp.history.execute(new SetScaleCommand(this, object, object.scale, this.objectScaleOnDown))
          }
          break
      }
    }
    gapp.controls.enabled = true
  })
}

保存对象

其实这里和我Low Code的思想很像,就是我们最终要将所有配置好的物体信息保存成一个JSON的形式。以便于在任意其它项目中做回显。怎么回显呢? 假如说我们现在编辑好一个灯光的位置信息以及通过gui调整好的颜色、亮度等,我们可以将该灯光object对象通过toJSON转成JSON后存储于我们最终对象中,后续通过接口取回JSON通过转化重新add到场景中即可

//转化为threejs特有的json格式
 scene.toJSON()
 (了解过json的同学可以发现,threejs为了缩小大小,将瓦片对象最大限度的拆分材质等,通过id关联并保存为json)
//解析json转为对象
Viewer.prototype.fromJSON = function (json, layeridx, isRayobj) {
  return new Promise((resolve, reject) => {
    // 解析 json 对象
    let loader = new THREE.ObjectLoader();
    let loadedMesh = loader.parse(json);
    let scene = this.mergeToMaterialsMap(loadedMesh, true)
    resolve(scene)
  })
}

结语

这篇文章主要介绍思想,相对来说这篇文章比较基础,当然后续可以根据自己的要求进行扩展

到此这篇关于threejs全景图和锚点编辑的文章就介绍到这了,更多相关threejs全景图和锚点编辑内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 基于Three.js插件制作360度全景图

    这是个基于three.js的插件,预览地址:戳这里 使用方法: 1.这个插件的用法很简单,引入如下2个js <script src="js/three.min.js"></script> <script src="js/photo-sphere-viewer.min.js"></script> 2.初始化一下,(具体各种参数配置根据情况而定) var PSV = new PhotoSphereViewer({ // 全

  • THREE.JS入门教程(6)创建自己的全景图实现步骤

    译序 Three.js是一个伟大的开源WebGL库,WebGL允许JavaScript操作GPU,在浏览器端实现真正意义的3D.但是目前这项技术还处在发展阶段,资料极为匮乏,爱好者学习基本要通过Demo源码和Three.js本身的源码来学习. 0.简介 全景图非常酷.使用Three.js做一个属于自己的全景图并不是那么困难. 要做一个全景图,你需要一个软件用来做一张全景图片(译者注:如果你没有那些特殊的设备).我使用了iPhone上的Microsoft Photosynth软件来制作. 1.环境

  • 基于Three.js实现360度全景图片

    Three.js 是一款运行在浏览器中的3D引擎, 处理三维效果.在一些相机的官网首页中,经常有一张图在旋转,图上面悬浮着文字.这种效果是如何做出来的呢?先看效果,再讲解. 1).建立一个java web 工程(或者其他工程), 因为three.js 的全景图要通过服务端浏览(安全的考虑) 2).在上面的结构中,只有css中的index.css是自定义的,其余css和js都属于three.js自带的工具文件.包含图片在内,已经上传资源了,点击此处下载. 3).index.jsp <%@ page

  • threejs全景图和锚点编辑的实现方案

    目录 全景图和锚点编辑 全景图 全景图拆解 场景编辑方案 transformControls 初始化控制器 添加可移动对象 平移.缩放.旋转 保存对象 结语 全景图和锚点编辑 今天来简单聊聊threejs全景图和锚点编辑的方案. 全景图也就是所谓的天空盒子,所应用到的场景例如:场景模型的天空背景.夜晚的星空背景.VR看房等~ 锚点编辑这篇重点讲一讲锚点编辑,也就是所谓场景编辑的方案.其中思想无限接近于Low Code,说到Low Code!我拖更了四篇文章,由于过年那段时间太忙了,实在是没时间更

  • Redis可视化客户端小结

    Redis是一个超精简的基于内存的键值对数据库(key-value),一般对并发有一定要求的应用都用其储存session,乃至整个数据库. redis的可视化客户端目前较流行的有三个:Redis Client ; Redis Desktop Manager ; Redis Studio. Redis Desktop Manager 下载地址:https://www.7down.com/soft/315212.html 一款基于Qt5的跨平台Redis桌面管理软件 支持: Windows 7+,

  • react 表单数据形式配置化设计

    目录 前言 实现 一般实现 配置化的实现 实现思路 具体实现 使用示例 总结 前言 在日常的中后台系统开发中,表单是和我们打交道非常多的名词.但是在一般的表单实现中.我们会做着很多重复的工作,不停在写 FormItem...,以及为组件加上“请输入/请选择”等无脑的 placeholder 文本和“请输入xx/请选择xx”等必填提示.其次表单一般都存在编辑页和详情页,而为了代码更好的维护性通常会将编辑和详情用一套代码实现.此时我们的代码里就会出现“isEdit ? 表单组件 : 纯文本”这样无脑

  • React + Threejs + Swiper 实现全景图效果的完整代码

      咱先看看全景图实现效果:展示地址   截图:   体验了一下是不是感觉周围环境转了一圈,感觉世界是圆的?

  • 使用 React 和 Threejs 创建一个VR全景项目的过程详解

    最近我在学习使用 React 配合 Three.js 来搭建一个可以浏览720全景图片的项目 实现的是加载一张 2:1 的720全景 分享一下我的创建过程 一.搭建框架并安装需要的插件 npx create-react-app parano // 创建一个 React 项目 npm install -S typescript // 安装 typescript,这个是类型辅助插件,与全景项目关系不大 npm install -S @types/three // 安装 typescript 支持的

  • 如何在vue3.0+中使用tinymce及实现多图上传文件上传公式编辑功能

    相关文档 本文部分内容借鉴: https://www.cnblogs.com/zhongchao666/p/11142537.html tinymce中文文档: http://tinymce.ax-z.cn/ 安装tinymce 1.安装相关依赖 yarn add tinymce || npm install tinymce -S yarn add @tinymce/tinymce-vue || npm install @tinymce/tinymce-vue -S 2.汉化编辑器前往此地址下载

  • AngularJS表单编辑提交功能实例

    研究了下高大上的AngularJS决定试试它的表单编辑提交功能,据说比JQuery强的不是一星半点. 好奇呀,试试吧.....搞了好久,尼玛...靠..靠..靠..尼玛 ..靠..靠....好吧,谁让我手欠呢. 搜索到了很多关于AngularJS Form的案例 如: http://www.angularjs.cn/A08j https://github.com/tiw/angularjs-tutorial https://github.com/tiw/angularjs-tutorial/bl

  • 当编辑框内容改变 对应的单元格也随着改变vba代码

    当编辑框内容改变,对应的单元格也随着改变 复制代码 代码如下: Private Sub TextBox1_Change() ThisWorkbook.ActiveSheet.Range("J1") = TextBox1.Text End Sub 利用这个代码可以写很多自动计算的Excel小模块了

  • jqgrid实现简单的单行编辑功能

    本文实例为大家分享了jqgrid实现简单的单行编辑功能的具体代码,供大家参考,具体内容如下 1.html代码 <table id="tableList" style="text-align:center;"></table> <div id=tablePager></div> 2.script代码 <script type="text/javascript"> var lastId;//

  • ExtJS中设置下拉列表框不可编辑的方法

    ExtJS这个框架,并没有学习和用过,只知道是一个流行的前段框架,和Easy UI,BUI,DWZ等这些框架都是差不多的,只不过比他们更加强大而已,之所以写这个,我觉得还是很有帮助的. 今天朋友遇到了一个问题:ExtJS中的下拉列表如何设置不可编辑的,html中是不可以编辑的,但是现在这种UI框架中的下拉列表框都是可以编辑的,朋友的需求就是像html中的那样效果,所以朋友想到了用editable属性,但是写了这个属性之后就报错了,当时并没有看错误,我给他找了1个属性设置为不可编辑的,但是还是不好

随机推荐