最近在做的项目中遇到需要保存当前的3d管道视角设置的问题,用户希望在对3d场景内的管道进行了缩放、旋转、移动之后可以将场景当前的视角状态保存在数据库中,并在下次加载时读取。 经过不断的尝试和研究,在同事的帮助下总算完成,下面说一下注意事项并附上实现代码。

首先,经过测试保存视角取决于两个部分,一个是camera这个超大的js对象,另一个就是右键平移执行的操作在controls中(开发中使用的是TrackballControls.js)。

先来说camera这个对象参数非常多,详细参数不再做说明,大家可以直接参考Three.js的 camera定义部分的源码,主要有up(相机的z坐标方向)、position(相机位置)、rotation(相机旋转,里面又包含_quaternion)、scale(比例),除了这些之外还有matrix、matrixWorld、matrixWorldInverse、projectionMatrix这几4×4的矩阵,另外还有far、aspect、near参数。这些因素共同决定了相机的视角。要逐个保存这些数据是一项相当繁琐的工作,因此我们想办法将这些对象合并成一个json字符串并在读取时将它们反转。

首先考虑的自然是 JSON.stringify() ,使用该方法转字符串的时候在谷歌浏览器下提示 循环引用的对象(貌似是谷歌的BUG,FF下应该是正常的未测试),因此无法转换,找了一下相关文章发现该方法可以传递一个自定义函数进来,避免循环对象的引用。如下所示

var tc = camera.clone();
var cache = [];
var pdata = JSON.stringify(tc, function(key, value) {
if (typeof value === 'object' && value !== null) {
if (cache.indexOf(value) !== -1) {
// Circular reference found, discard key
return;
}
// Store value in our collection
cache.push(value);
}
return value;
});
cache = null; // Enable garbage collection

这样就可以将camera的参数保存为一个json字符串形式从而可以保存到数据库中。

对于平移的保存,查看TrackballControls.js文件即可找到 控制平移的参数为 controls.target 为一个THREE.Vector3的向量类型,那很轻易的就可以将其保存,如下所示我们将上面的camera和controls.target合并为一个JSON字符串并保存到数据库中即可。

var target0 = controls.target.clone();
var ptarget = JSON.stringify(target0);
pdata = '{"cam":'+pdata+',"ctrl":'+ptarget+'}';

上面的方式一般都可以想得到,关键是如何将这个json字符串读取出来并完整的赋值给新的camera对象。

我们使用ajax读取后,并将其反转为JSON对象即  :

var r = JSON.parse(d.angleView);  //d.angleView为数据库中读取出来的视角字符串参数

//关键在这里,使用jquery的extend方法合并相机参数与反转过来的json对象,其中的camera为全局的camera对象,页面初始化时已经定义,此处clone是新生成一个对象,因为camera的赋值均为引用赋值非直接赋值,类似传址
var tcamera = $.extend(true, {}, camera.clone(), r.cam);
var tctrl = new THREE.Vector3(r.ctrl.x,r.ctrl.y,r.ctrl.z); camera = tcamera.clone();
controls = new THREE.TrackballControls(camera, renderer.domElement); //重新为相机加载控制器
camera.updateProjectionMatrix(); //更新相机 controls.target.copy(tctrl);//更新控制器的中心点 copy方法可以在TrackballControls.js中找到

这样 我们就完整的实现了保存相机视角的功能。

最新文章

  1. Liferay7 BPM门户开发之46: 集成Activiti用户、用户组、成员关系同步
  2. sql 查询 – left join on
  3. codevs1064 虫食算
  4. WPF编译时提示“...不包含适合于入口点的静态‘Main’方法 ...”
  5. hdu 1423 最长公共递增子序列
  6. Delphi窗体中禁用最大化按钮
  7. Effective C++ 笔记一 让自己习惯C++
  8. Android状态栏颜色修改
  9. 第16讲- UI组件之TextView
  10. eclipse中的两种Jre 及 Jre与Jdk的区别
  11. 学JAVA第二十天,接触异常处理,自定义异常
  12. NodeJs操作MongoDB之多表查询($lookup)与常见问题
  13. Go之十大经典排序算法
  14. HTML入门12
  15. C# 初识Redis
  16. C# 开发Modbus Rtu客户端 modbus测试Demo,Modbus 串口通信 , 虚拟MODBUS-RTU测试
  17. windows 安装lua-5.3.4 --引用自https://blog.csdn.net/wangtong01/article/details/78296369
  18. idea2018.2.4的安装激活与热部署插件JRebel的激活方法
  19. hbase 自定义过滤器
  20. 加快android studio 编译速度

热门文章

  1. hdu4678 Mine 2013 Multi-University Training Contest 8 博弈题
  2. Linux修改hostname的几种方法
  3. angualrJs清除定时器
  4. EasyUI DataGrid 基于 Ajax 自定义取值(loadData)
  5. jquery各种事件使用方法总结(from:天宇之游)
  6. 【学习】js学习笔记---数组对象
  7. d3力导向图聚焦
  8. WPF DataGrid自动生成序号
  9. Thinking in React Implemented by Reagent
  10. nexus3 添加第三方本地文件jar到仓库