HTML5技术

首个threejs项目-前端填坑指南 - At丶Sea(3)

字号+ 作者:H5之家 来源:博客园 2016-03-05 11:00 我要评论( )

模型已经放大显示在屏幕中,然后点击关闭按钮让模型回到原位这个就直接用TweenMax将相机的position值设置为初始值就可以了。 接下来就是开发用手指操作模型旋转的功能了。 七、操作模型旋转 这个功能我卡了好久,里

模型已经放大显示在屏幕中,然后点击关闭按钮让模型回到原位这个就直接用TweenMax将相机的position值设置为初始值就可以了。

接下来就是开发用手指操作模型旋转的功能了。


七、操作模型旋转

这个功能我卡了好久,里面涉及到数学中的矩阵、四元数、欧拉角、向量乘积、轴-角啥的,完全都忘了。在二维中旋转可以通过角度来控制,而在三维空间中需要通过四元数或者矩阵来实现,万般无奈只能求助万能的google来了解怎么在三维空间中对物体进行旋转操作。 通过了解在3D中表现旋转有三种方法,矩阵、欧拉角、四元组。 最后选用四元组来实现旋转的方法,简单点说原因就是四元组的是围绕一个轴来做旋转,而且在threejs中也提供了THREE.Quaternion()方法,然后在threejs的包中找到了一些写好的鼠标控制的类(TrackballControls.js、OrbitControls.js等),然后参考着源码,将方法虽然写出来了,但是有时候操作起来会有意向不到的bug,所以里面的细节还有待深挖。下面简述一下旋转的思路。

首先四元数控制旋转需要的是一个旋转轴和一个旋转弧度,直接上图清楚明了


图十 


然后就想办法得到这个两个东西,接着开始想怎么弄到旋转弧度,首先获取到点击开始和结束的x,y值,然后得到两个向量之间的夹角,得到一个弧度,然后在设置一个默认的旋转系数,两者相乘得到弧度。接着通过开始和结束的向量乘积得到旋转轴,最后通过setFromAxisAngle(axis, angle)得到旋转四元数。

核心代码如下:

function rotateMatrix(rotateStart, rotateEnd){ var axis = new THREE.Vector3(), quaternion = new THREE.Quaternion(); angle = Math.acos(rotateStart.dot(rotateEnd) / rotateStart.length() / rotateEnd.length()); if (angle){ //如果夹角等于0, 说明物体没有旋转 axis.crossVectors(rotateStart, rotateEnd).normalize(); //rotateStart,rotateEnd向量乘积 标准化 得到旋转轴 angle *= _that.rotationSpeed; //rotationSpeed旋转系数 得到旋转弧度 quaternion.setFromAxisAngle(axis, angle); //从一个旋转轴和旋转弧度得到四元组, 如果要让物体相反方向旋转 设置angle为负 } return quaternion; //返回一个旋转的四元数 } this.handleRotation = function(object){ _that.rotateEndPoint = _that.projectOnTrackball(_that.deltaX, _that.deltaY); var rotateQuaternion = rotateMatrix(_that.rotateStartPoint, _that.rotateEndPoint); var curQuaternion = object.quaternion; curQuaternion.multiplyQuaternions(rotateQuaternion, curQuaternion); //设置四元组 a x b curQuaternion.normalize(); object.setRotationFromQuaternion(curQuaternion); //方法通过规范化的旋转四元数直接应用旋转 参数必须normalize() };

 

在这里有个小坑,就是所有模型的外观大小不同,当旋转的时候,可能会出现误操作,然后用了一个小技巧就是用一个透明的方体包裹模型,这样做就相当于旋转一个cube了,而且设置方体有网格时对排除bug有帮助。如下图所示:


图十一 (外层包裹框)


虽然旋转的效果做出来了,但是旋转里面涉及的东西还有一些理解的不是很清楚,还需要继续深入研究,等我研究透彻了再重新整理一下(还望大神指点一下)。

参考:四元数旋转、cube旋转、TrackballControls.js源码

八、 灯光

最后就是灯光的控制,因为NBA的主色调是红蓝色,设计大神就想模型在页面中有红蓝光打在模型上的感觉,于是照着这个方向,他开始在软件中调试灯光,调整好之后我按照设计师在软件中调整好的位置摆放灯光,发现跟预想的有点差异,页面中的颜色显的太深了,于是在整个空间中加上了一个白色的全局光来提亮整体的亮度,然后对灯光进行反复的调整,就到了现在页面中呈现的样子了。灯光调整的过程如图所示:


图十二 (灯光调整过程)

注: threejs提供很多种灯光具体可以在threejs文档中查看,而灯光调整可以借助threejs提供的辅助线来调整,THREE.PointLightHelper()、THREE.SpotLightHelper()等。这样有助于迅速定位到问题。

最后就是手机兼容性的测试了(因为是微信的活动页,所以其它浏览器未测试)。在iPhone下整体体验较好,在Android下使用r71版本发现模型会出现菱角不分明的情况如图三所示,之后改用r72版本,用高版本的Android测试发现问题解决了,然后拿我自己的mx2测试时出现另外一个问题,直接卡在加载页面进不去页面,然后通过调试工具发现在控制台中有方法报错(小米2也是同等情况),倒腾了好久,然而并没有什么卵用,因为是threejs内部报错,无奈只能放大招,做一个Android版本来解决这个问题。

最后附上体验地址(页面中意想不到的bug肯定是还有的):


扫码体验


第一次在实战中使用threejs开发,还有很多的不足需要弥补,希望下一次能做的更好。自己也继续的在webgl的坑中挣扎,挣扎,挣扎(重要的要说三遍),还望有大神指点迷津!!

附上公司大神设计师的站酷:

另外附上一些自己在填坑中找到的对3D学习有帮助的网站、博客、书籍:

各种计算  
许多有趣的东西  
大叔很厉害的 
threejs源码注释 https://github.com/omni360/three.js.sourcecode 

关于threejs的书籍只有英文原版的:

《Three.Js Essentials》、《threejs-cookbook》、《Learning Three.js》

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 【Vue 入门】使用 Vue2 开发一个展示项目列表的应用 - zhangjk

    【Vue 入门】使用 Vue2 开发一个展示项目列表的应用 - zhangjk

    2017-04-30 16:00

  • 如何做好项目管理任务分配 - CharlieChu

    如何做好项目管理任务分配 - CharlieChu

    2017-04-27 15:00

  • vue2.0版cnode社区项目搭建及实战开发 - sandisen

    vue2.0版cnode社区项目搭建及实战开发 - sandisen

    2017-04-20 14:00

  • 前端项目从0到1的感悟 - liliangel

    前端项目从0到1的感悟 - liliangel

    2017-04-20 12:00

网友点评
r