公司做商城、消防、用电等项目,需要实现楼层和设备的可视化,以前都是使用其他建模工具创建的整体模型,再使用三。射流研究…的加载器加载到场景中,但是这样的加载存在缺陷,比如不能给模型的元素赋属性、不能单个点击元素、渲染单调等。所以本次参考了一些资料,不使用模型倒入,完全使用三。射流研究…搭建场景,代码有些粗燥勿怪。
1.创建地板
地板是一个类似盒子,有顶部有底部有侧面,但是不一定是规则的盒子,因此我放弃了常用的盒几何的方式,改用顶点面的形式创建任意多边形地板,已知多边形底部坐标,底部坐标加上高度得到顶部坐标,通过挖耳朵可以计算出底部和顶部的三角面,侧面的三角面可以直接通过坐标序号得到,由此可以创建一个通用的几何学。
地板。原型。getgeometry=函数(点,高度){ var TopPoints=[];for(var I=0;IPO ints . LengIti){ var vertice=points[I];托普点。推送([顶点[0],顶点[1]高度,顶点[2]]);} var TotalPoints=点数。concat(TopPointS);定义变量顶点=[];//所有的顶点for(var I=0;itotalPoints . lengthi){ 0顶点。推送(新三Vector3(totalPoints[i][0],totalPoints[i][1],total points[I][2])} var length=points。长度;var faces=[];for(var j=0;jlengthj ){ //侧面生成三角形if(j!=length-1){ faces.push(新三.面3(j,j 1,长度j 1));推(新三。面3(长度j 1,长度j,j));}else{ faces.push(new THREE .面3(j,0,长度));推(新三。面3(长度,长度j,j));} } var数据=[];for(var I=0;ileng tti){ data . push(点[i][0],点[一][二]);} var三角形=earcut。三角测量(数据);如果(三角形三角形。长度!=0){ for(var I=0;itr iangles . lengthi){ var tle length=三角形。titlengthif(I % 3==0 I tle length-2){ faces。推动(新的三.Face3(三角形[i],三角形[I ^ 1],三角形[I ^ 2]);//底部的三角面推(新三。面3(三角形[i]长度,三角形[i 1]长度,三角形[i 2]长度));//顶部的三角面} } } var几何=新三.几何();几何。顶点=顶点;几何。面=面;几何学。computefacnenormass();//自动计算法向量返回几何;}效果:
2.创建墙体
墙体我使用了盒子几何,墙体上的窗户的洞、门洞,我们可以使用三英国标准管螺纹(British Standard Pipe)库中差集函数来进行模型相减来实现。
Floor.prototype.addWall=函数(大小、位置、旋转、孔){ var geometry=new THREE .BoxGeometry(大小[0],大小[1],大小[2]);var materials=new THREE .MeshLambertMaterial({ color :0xb CEE 0,side:THREE .DoubleSide}) var结果=新三.网格(几何图形、材料);if(holes){ result=cube;for(var I=0;IHO les . LengTii){ var total Bsp=new TripBsp(结果);var hole=holes[I];可变孔几何=新三.BoxGeometry(孔. size[0],孔. size[1],孔。大小[2]);var holeCube=new THREE .网格(孔几何);孔立方体。位置。x=孔。位置[0];孔立方体。位置。y=孔。定位[1]孔。尺寸[1/2 ];孔立方体。位置。z=孔。位置[2];var clip bsp=新增三个bsp(孔立方体);var resultBSP=totalBSP。减法(剪辑bsp);结果=resultbsp。tomesh();} result . material=materials } this . container . add(结果);//添加填充}效果:
3.门框
在添加门之前,为了更加形象一点,我添加了门框。先使用墙体减去门框的洞,再添加减去门洞的门框,跟前面类似,具体代码不放了。
效果:
4.门、窗、主机、显示屏、桌子
门、窗、主机、显示屏、桌子我都是使用盒几何的形式,再给相应的面贴纹理,跟前面类似,效果如下:
5.盆栽
盆栽的盆体可以使用圆柱抛光测量法来创建顶部大于底部的圆台,盆栽的叶子是使用多个平面几何贴上植物纹理以不同的角度展示,代码如下:
//盆栽地板。原型。addPlaN=函数(位置、比例){ var plant=new THREE .对象3D();变化几何=新三。气缸缓冲测量法(0.15,0.1,0.4,22);可变材料=新的三.MeshLambertMaterial({ color :0x ffffff });可变气缸=新三缸。网格(几何、材料);柱面。位置。x=0;气缸位置=0.2柱面。位置。z=0;plant.add(气缸);var leafTexture=new THREE .TextureLoader().负载('会议/工厂。png ');var leafMaterial=new THREE .网状基本材料(地图:叶子纹理,侧面:纹理.DoubleSide,透明: true });var geom=new THREE .平面几何(0.4,0.8);for(var I=0;i4;i ){ var leaf=new THREE .网格(geom,叶材料);叶子位置=0.8叶子。旋转y=-数学/(I ^ 1);plant.add(叶);} plant.position.x=位置[0];工厂.位置. y=位置[1];plant.position.z=位置[2];this.container.add(植物);}效果(很粗燥):
6.椅子
椅子的模型有点复杂,因为这个差点放弃用三创建椅子,但看到一个同行完全用三创建的迷你城市,又有了信心和勇气。于是:4条椅子腿定位旋转、椅子面、2条靠背腿定位旋转、靠背定位旋转,最终创建完成,代码太丑陋就不上了。效果:
7.开门动画
开门动画我使用了在两者之间库,Tween.js是一个包含各种经典动画算法的射流研究…资源,动态改变门在z轴方向上的值。
如果(状态=='关闭'){ 0状态=' openvar desRotation=Math。PI/2;新TWEEN .补间(门。旋转)。to({ y: desRotation },10000).放松(TWEEN .放松,有弹性,放松)。onComplete(function(){ }).start();} else {状态='关闭新的TWEEN .补间(门。旋转)。to({ y: 0 },10000).放松(TWEEN .放松,有弹性,放松)。onComplete(function(){ }).start();}效果:
8.行走动画
行走动画我使用了三的动画模块,导入带动画的格式模型,关于模型动画的制作很复杂,我们可以在网络上下载。导入动画之后播放动画。
var Mixers=[];定义变量动画;var walking manvar loader=new THREE .fbxlloader();装载机。装载('文件/行走人。' fbx ',函数(对象){//Samba跳舞。fbx对象。混音器=新的三.动画混合器(对象);混合器。推送(对象。混合器);//动画混合器动画=对象。混合器。剪辑动作(对象。AnimationMixer[0]);//动画动作动画剪辑行走的人=对象;会走路的人。规模。x=行走的人。规模。y=行走的人。规模。z=0.8会走路的人。位置。x=第一点[0];会走路的人。位置。y=第一点[1];会走路的人。位置。z=第一点[2];walkingMan.rotation.y=旋转;//角度根据当前点和下一个点计算场景添加(行走的人);动画。play();});函数updateWalkingMan(){ if(mixers。长度0){ for(var I=0;混合器长度;I){ 0混合器[ i ].更新(时钟。getdelta());//时钟。getdelta()} } }函数render(){ updateWalkingMan();requestAnimationFrame(渲染);renderer.render(场景、摄像机);}效果:
在播放动画的同时,我们可以更改人物模型的位置、角度,达到在场景中走动的效果:
会议室建模告一段落,这也是一次探索吧。后续的目标是封装常用的模型、在网中建立用户交互的建模方式,更加标准、快速的搭建室内场景。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。