使用three.js创建3D机房模型-分享一
序:前段时间公司一次研讨会上,一市场部同事展现了同行业其他公司的3D机房,我司领导觉得这个可以研究研究,为了节约成本,我们在网上大量检索,最后找到一位前辈的博文【TWaver的技术博客】,在那篇博文的评论区终于找到了那位前辈的源码,可惜下载后发现是压缩过的.min.js文件。经过各种研究发现,那是人家公司自己卖钱的库,不能完全共享,所以我司决定,派本人研究一下web3D的技术,于是乎便有了下面的技术分享。
一、本着开源的思想,使用three.js框架,封装常用的模型库。先学着那位前辈的样子,使用ThreeJS画出类似的效果图,只是稍微有点丑,看官莫怪。
特此申明:里面的大部分模型贴图都是使用的上述前辈的图片
二、源码
首先是各种库的引入
<script src="../webglJS/jquery-2.2.2.js"></script>
<script src="../webglJS/three.min.js"></script>
<script src="../webglJS/stats.min.js"></script>
<script src="../webglJS/OrbitControls.js"></script>
<script src="../webglJS/ThreeBSP.js"></script>
<script src="../webglJS/Tween.js"></script>
上述几个库都是网上可以下载到的。
然后是封装自己的模型库,这是初始的模型库,较为简陋了 ,牛逼的库都是不断的迭代个几百次的,不到的地方还望指正,互相学习共同进步
--这里封装一下 就叫做msj3D.js--
1 /* 2 作者:yeyunfei 3 创建时间:2016-11-28 4 版本:V16.11.01.bug 5 功能描述:用户创建web版组态 6 7 使用方式 8 var msjstation=new msj3D(); 9 msjstation.initmsj3D(‘divid‘,{...},[datajson]); 10 msjstation.start(); 11 */ 12 function msj3D() { } 13 var msj3DObj = null; 14 msj3D.prototype.start = function () { 15 //此处用于判断浏览器 16 17 //开始 18 var _this = this; 19 msj3DObj = _this; 20 _this.initThree(_this.fId); 21 _this.initCamera(); 22 _this.initScene(); 23 _this.initHelpGrid(); 24 _this.initLight(); 25 _this.addTestObj(); 26 //添加3D对象 27 $.each(_this.objList, function (index,_obj) { 28 _this.InitAddObject(_obj); 29 }); 30 _this.initMouseCtrl(); 31 //创建按钮 32 _this.addBtns(_this.btns); 33 34 _this.animation(); 35 36 } 37 /* 38 方法:初始化 39 fid 画布所属div的Id 40 option:参数 { 41 antialias:true,//抗锯齿效果为设置有效 42 clearCoolr:0xFFFFFF, 43 showHelpGrid:false,//是否显示网格线 44 } 45 */ 46 msj3D.prototype.initmsj3D = function (_fId, _option,_datajson) { 47 //参数处理 48 this.option = new Object(); 49 this.option.antialias = _option.antialias || true;//刷新色 50 this.option.clearCoolr = _option.clearCoolr || 0x1b7ace;//刷新色 51 this.option.showHelpGrid = _option.showHelpGrid || false;//刷新色 52 //对象 53 this.fId = _fId; 54 this.width = $("#" + _fId).width(); 55 this.height = $("#" + _fId).height(); 56 this.renderer = null;//渲染器 57 this.camera = null;//摄像机 58 this.scene = null;//场景 59 this.SELECTED=null; 60 this.objects = []; 61 this.mouseClick = new THREE.Vector2(); 62 this.raycaster = new THREE.Raycaster(); 63 this.controls = null;//鼠标控制器 64 this.objList = _datajson.objects;//对象列表 65 this.eventList = _datajson.events;//事件对象列表 66 this.btns = _datajson.btns;//按钮列表 67 var _this = this; 68 } 69 //初始化渲染器 70 msj3D.prototype.initThree = function () { 71 var _this = this; 72 _this.renderer = new THREE.WebGLRenderer({ alpha: true, antialias: _this.option.antialias }); 73 _this.renderer.setSize(_this.width, _this.height); 74 $("#" + _this.fId).append(_this.renderer.domElement); 75 _this.renderer.setClearColor(_this.option.clearCoolr, 1.0); 76 _this.renderer.shadowMap.enabled = true;// 77 _this.renderer.shadowMapSoft = true; 78 //事件 79 _this.renderer.domElement.addEventListener(‘mousedown‘, _this.onDocumentMouseDown, false); 80 _this.renderer.domElement.addEventListener(‘mousemove‘, _this.onDocumentMouseMove, false); 81 } 82 //初始化摄像机 83 msj3D.prototype.initCamera = function () { 84 var _this = this; 85 _this.camera = new THREE.PerspectiveCamera(45, _this.width / _this.height, 1, 100000); 86 _this.camera.name = ‘mainCamera‘; 87 _this.camera.position.x =0; 88 _this.camera.position.y =1000; 89 _this.camera.position.z =-1800; 90 _this.camera.up.x = 0; 91 _this.camera.up.y =1; 92 _this.camera.up.z =0; 93 _this.camera.lookAt({ x: 0, y: 0, z: 0 }); 94 _this.objects.push(_this.camera); 95 } 96 //创建场景 97 msj3D.prototype.initScene=function() { 98 var _this = this; 99 _this.scene = new THREE.Scene(); 100 } 101 //添加对象 102 msj3D.prototype.addObject = function (_obj) { 103 var _this = msj3DObj; 104 _this.objects.push(_obj); 105 _this.scene.add(_obj); 106 } 107 //创建网格线 108 msj3D.prototype.initHelpGrid = function () { 109 var _this = this; 110 if (_this.option.showHelpGrid) { 111 var helpGrid = new THREE.GridHelper(1000, 50); 112 _this.scene.add(helpGrid); 113 } 114 } 115 //灯光布置 116 msj3D.prototype.initLight = function () { 117 /* 118 AmbientLight: 环境光,基础光源,它的颜色会被加载到整个场景和所有对象的当前颜色上。 119 PointLight:点光源,朝着所有方向都发射光线 120 SpotLight :聚光灯光源:类型台灯,天花板上的吊灯,手电筒等 121 DirectionalLight:方向光,又称无限光,从这个发出的光源可以看做是平行光. 122 */ 123 var _this = this; 124 var light = new THREE.AmbientLight(0xcccccc); 125 light.position.set(0, 0,0); 126 _this.scene.add(light); 127 var light2 = new THREE.PointLight(0x555555); 128 light2.shadow.camera.near =1; 129 light2.shadow.camera.far = 5000; 130 light2.position.set(0, 350, 0); 131 light2.castShadow = true;//表示这个光是可以产生阴影的 132 _this.scene.add(light2); 133 134 } 135 //创建鼠标控制器 136 msj3D.prototype.initMouseCtrl=function() { 137 var _this = this; 138 _this.controls = new THREE.OrbitControls(_this.camera); 139 _this.controls.addEventListener(‘change‘, _this.updateControls); 140 } 141 //控制器回调 142 msj3D.prototype.updateControls = function () { 143 144 //controls.update(); 145 } 146 //循环渲染界面 147 msj3D.prototype.animation = function () { 148 var _this = msj3DObj; 149 if (TWEEN != null && typeof (TWEEN) != ‘undefined‘) { 150 TWEEN.update(); 151 } 152 requestAnimationFrame(_this.animation); 153 _this.renderer.render(_this.scene, _this.camera); 154 } 155 156 /* 157 添加对象 158 */ 159 msj3D.prototype.InitAddObject = function (_obj) { 160 var _this = this; 161 if (_obj.show == null || typeof (_obj.show) == ‘undefined‘ || _obj.show) { 162 var _tempObj = null; 163 switch (_obj.objType) { 164 case ‘cube‘: 165 _tempObj = _this.createCube(_this, _obj); 166 _this.addObject(_tempObj); 167 break; 168 case ‘floor‘: 169 _tempObj = _this.CreateFloor(_obj) 170 _this.addObject(_tempObj); 171 break; 172 case ‘wall‘: 173 _this.CreateWall(_this,_obj); 174 break; 175 case ‘plane‘: 176 _tempObj = _this.createPlaneGeometry(_this, _obj); 177 _this.addObject(_tempObj); 178 break; 179 case ‘glasses‘: 180 _this.createGlasses(_this, _obj); 181 break; 182 case ‘emptyCabinet‘: 183 _tempObj = _this.createEmptyCabinet(_this, _obj); 184 _this.addObject(_tempObj); 185 break; 186 case ‘cloneObj‘: 187 _tempObj = _this.commonFunc.cloneObj(_obj.copyfrom, _obj); 188 _this.addObject(_tempObj); 189 break; 190 } 191 } 192 } 193 194 //创建地板 195 msj3D.prototype.CreateFloor = function (_obj) { 196 var _this = this; 197 var _cube = _this.createCube(_this, _obj); 198 return _cube; 199 } 200 //创建墙体 201 msj3D.prototype.CreateWall = function (_this, _obj) { 202 if (_this == null) { 203 _this = this; 204 } 205 var _commonThick = _obj.thick || 40;//墙体厚度 206 var _commonLength = _obj.length || 100;//墙体厚度 207 var _commonHeight = _obj.height || 300;//强体高度 208 var _commonSkin = _obj.style.skinColor || 0x98750f; 209 //建立墙面 210 $.each(_obj.wallData, function (index, wallobj) { 211 var wallLength = _commonLength; 212 var wallWidth = wallobj.thick||_commonThick; 213 var positionX = ((wallobj.startDot.x||0) + (wallobj.endDot.x||0)) / 2; 214 var positionY = ((wallobj.startDot.y || 0) + (wallobj.endDot.y || 0)) / 2; 215 var positionZ = ((wallobj.startDot.z || 0) + (wallobj.endDot.z || 0)) / 2; 216 //z相同 表示x方向为长度 217 if (wallobj.startDot.z == wallobj.endDot.z) { 218 wallLength = Math.abs(wallobj.startDot.x - wallobj.endDot.x); 219 wallWidth = wallobj.thick || _commonThick; 220 } else if (wallobj.startDot.x == wallobj.endDot.x) { 221 wallLength = wallobj.thick || _commonThick; 222 wallWidth = Math.abs(wallobj.startDot.z - wallobj.endDot.z); 223 } 224 var cubeobj = { 225 length: wallLength, 226 width: wallWidth, 227 height: wallobj.height || _commonHeight, 228 rotation: wallobj.rotation, 229 x: positionX, 230 y: positionY, 231 z: positionZ, 232 uuid: wallobj.uuid, 233 name:wallobj.name, 234 style: { 235 skinColor: _commonSkin, 236 skin:wallobj.skin 237 } 238 } 239 var _cube = _this.createCube(_this, cubeobj); 240 if (_this.commonFunc.hasObj(wallobj.childrens) && wallobj.childrens.length > 0) { 241 $.each(wallobj.childrens, function (index, walchildobj) { 242 var _newobj = null; 243 _newobj = _this.CreateHole(_this, walchildobj); 244 _cube = _this.mergeModel(_this, walchildobj.op, _cube, _newobj); 245 }); 246 } 247 _this.addObject(_cube); 248 }); 249 } 250 //挖洞 251 msj3D.prototype.CreateHole = function (_this, _obj) { 252 if (_this == null) { 253 _this = this; 254 } 255 var _commonThick = 40;//墙体厚度 256 var _commonLength = 100;//墙体厚度 257 var _commonHeight = 300;//强体高度 258 var _commonSkin = 0x98750f; 259 //建立墙面 260 var wallLength = _commonLength; 261 var wallWidth = _obj.thick || _commonThick; 262 var positionX = ((_obj.startDot.x || 0) + (_obj.endDot.x || 0)) / 2; 263 var positionY = ((_obj.startDot.y || 0) + (_obj.endDot.y || 0)) / 2; 264 var positionZ = ((_obj.startDot.z || 0) + (_obj.endDot.z || 0)) / 2; 265 //z相同 表示x方向为长度 266 if (_obj.startDot.z == _obj.endDot.z) { 267 wallLength = Math.abs(_obj.startDot.x - _obj.endDot.x); 268 wallWidth = _obj.thick || _commonThick; 269 } else if (_obj.startDot.x == _obj.endDot.x) { 270 wallLength = _obj.thick || _commonThick; 271 wallWidth = Math.abs(_obj.startDot.z - _obj.endDot.z); 272 } 273 var cubeobj = { 274 length: wallLength, 275 width: wallWidth, 276 height: _obj.height || _commonHeight, 277 rotation: _obj.rotation, 278 x: positionX, 279 uuid: _obj.uuid, 280 name: _obj.name, 281 y: positionY, 282 z: positionZ, 283 style: { 284 skinColor: _commonSkin, 285 skin: _obj.skin 286 } 287 } 288 var _cube = _this.createCube(_this, cubeobj); 289 return _cube; 290 } 291 //模型合并 使用ThreeBSP插件mergeOP计算方式 -表示减去 +表示加上 292 msj3D.prototype.mergeModel = function (_this, mergeOP, _fobj, _sobj) { 293 if (_this == null) { 294 _this = this; 295 } 296 var fobjBSP = new ThreeBSP(_fobj); 297 var sobjBSP = new ThreeBSP(_sobj); 298 // var sobjBSP = new ThreeBSP(_sobj); 299 var resultBSP = null; 300 if (mergeOP == ‘-‘) { 301 resultBSP = fobjBSP.subtract(sobjBSP); 302 } else if (mergeOP == ‘+‘) { 303 var subMesh = new THREE.Mesh(_sobj); 304 _sobj.updateMatrix(); 305 _fobj.geometry.merge(_sobj.geometry, _sobj.matrix); 306 return _fobj; 307 // resultBSP = fobjBSP.union(sobjBSP); 308 } else if (mergeOP == ‘&‘) {//交集 309 resultBSP = fobjBSP.intersect(sobjBSP); 310 } else { 311 _this.addObject(_sobj); 312 return _fobj; 313 } 314 var cubeMaterialArray = []; 315 for (var i = 0; i < 1; i++) { 316 cubeMaterialArray.push(new THREE.MeshLambertMaterial({ 317 //map: _this.createSkin(128, 128, { imgurl: ‘../datacenterdemo/res2/‘+(i%11)+‘.jpg‘ }), 318 vertexColors: THREE.FaceColors 319 })); 320 } 321 var cubeMaterials = new THREE.MeshFaceMaterial(cubeMaterialArray); 322 var result = resultBSP.toMesh(cubeMaterials); 323 result.material.shading = THREE.FlatShading; 324 result.geometry.computeFaceNormals(); 325 result.geometry.computeVertexNormals(); 326 result.uuid= _fobj.uuid+mergeOP+_sobj.uuid; 327 result.name=_fobj.name+mergeOP+_sobj.name; 328 result.material.needsUpdate = true; 329 result.geometry.buffersNeedUpdate = true; 330 result.geometry.uvsNeedUpdate = true; 331 var _foreFaceSkin = null; 332 for (var i = 0; i < result.geometry.faces.length; i++) { 333 var _faceset = false; 334 for (var j = 0; j < _fobj.geometry.faces.length; j++) { 335 if (result.geometry.faces[i].vertexNormals[0].x === _fobj.geometry.faces[j].vertexNormals[0].x 336 && result.geometry.faces[i].vertexNormals[0].y === _fobj.geometry.faces[j].vertexNormals[0].y 337 && result.geometry.faces[i].vertexNormals[0].z === _fobj.geometry.faces[j].vertexNormals[0].z 338 && result.geometry.faces[i].vertexNormals[1].x === _fobj.geometry.faces[j].vertexNormals[1].x 339 && result.geometry.faces[i].vertexNormals[1].y === _fobj.geometry.faces[j].vertexNormals[1].y 340 && result.geometry.faces[i].vertexNormals[1].z === _fobj.geometry.faces[j].vertexNormals[1].z 341 && result.geometry.faces[i].vertexNormals[2].x === _fobj.geometry.faces[j].vertexNormals[2].x 342 && result.geometry.faces[i].vertexNormals[2].y === _fobj.geometry.faces[j].vertexNormals[2].y 343 && result.geometry.faces[i].vertexNormals[2].z === _fobj.geometry.faces[j].vertexNormals[2].z) { 344 result.geometry.faces[i].color.setHex(_fobj.geometry.faces[j].color.r * 0xff0000 + _fobj.geometry.faces[j].color.g * 0x00ff00 + _fobj.geometry.faces[j].color.b * 0x0000ff); 345 _foreFaceSkin = _fobj.geometry.faces[j].color.r * 0xff0000 + _fobj.geometry.faces[j].color.g * 0x00ff00 + _fobj.geometry.faces[j].color.b * 0x0000ff; 346 _faceset =true; 347 } 348 } 349 if (_faceset == false){ 350 for(var j = 0; j < _sobj.geometry.faces.length; j++) { 351 if (result.geometry.faces[i].vertexNormals[0].x === _sobj.geometry.faces[j].vertexNormals[0].x 352 && result.geometry.faces[i].vertexNormals[0].y === _sobj.geometry.faces[j].vertexNormals[0].y 353 && result.geometry.faces[i].vertexNormals[0].z === _sobj.geometry.faces[j].vertexNormals[0].z 354 && result.geometry.faces[i].vertexNormals[1].x === _sobj.geometry.faces[j].vertexNormals[1].x 355 && result.geometry.faces[i].vertexNormals[1].y === _sobj.geometry.faces[j].vertexNormals[1].y 356 && result.geometry.faces[i].vertexNormals[1].z === _sobj.geometry.faces[j].vertexNormals[1].z 357 && result.geometry.faces[i].vertexNormals[2].x === _sobj.geometry.faces[j].vertexNormals[2].x 358 && result.geometry.faces[i].vertexNormals[2].y === _sobj.geometry.faces[j].vertexNormals[2].y 359 && result.geometry.faces[i].vertexNormals[2].z === _sobj.geometry.faces[j].vertexNormals[2].z 360 && result.geometry.faces[i].vertexNormals[2].z === _sobj.geometry.faces[j].vertexNormals[2].z) { 361 result.geometry.faces[i].color.setHex(_sobj.geometry.faces[j].color.r * 0xff0000 + _sobj.geometry.faces[j].color.g * 0x00ff00 + _sobj.geometry.faces[j].color.b * 0x0000ff); 362 _foreFaceSkin = _sobj.geometry.faces[j].color.r * 0xff0000 + _sobj.geometry.faces[j].color.g * 0x00ff00 + _sobj.geometry.faces[j].color.b * 0x0000ff; 363 _faceset = true; 364 } 365 } 366 } 367 if (_faceset == false) { 368 result.geometry.faces[i].color.setHex(_foreFaceSkin); 369 } 370 // result.geometry.faces[i].materialIndex = i 371 } 372 result.castShadow = true; 373 result.receiveShadow = true; 374 return result; 375 } 376 //创建盒子体 377 msj3D.prototype.createCube = function (_this, _obj) { 378 if (_this == null) { 379 _this = this; 380 } 381 var _length = _obj.length || 1000;//默认1000 382 var _width = _obj.width || _length; 383 var _height = _obj.height || 10; 384 var _x = _obj.x || 0, _y = _obj.y || 0, _z = _obj.z || 0; 385 var skinColor = _obj.style.skinColor || 0x98750f; 386 var cubeGeometry = new THREE.CubeGeometry(_length, _height, _width, 0, 0, 1); 387 388 //六面颜色 389 for (var i = 0; i < cubeGeometry.faces.length; i += 2) { 390 var hex = skinColor || Math.random() * 0x531844; 391 cubeGeometry.faces[i].color.setHex(hex); 392 cubeGeometry.faces[i + 1].color.setHex(hex); 393 } 394 //六面纹理 395 var skin_up_obj = { 396 vertexColors: THREE.FaceColors 397 } 398 var skin_down_obj = skin_up_obj, 399 skin_fore_obj = skin_up_obj, 400 skin_behind_obj = skin_up_obj, 401 skin_left_obj = skin_up_obj, 402 skin_right_obj = skin_up_obj; 403 var skin_opacity = 1; 404 if (_obj.style != null && typeof (_obj.style) != ‘undefined‘ 405 && _obj.style.skin != null && typeof (_obj.style.skin) != ‘undefined‘) { 406 //透明度 407 if (_obj.style.skin.opacity != null && typeof (_obj.style.skin.opacity) != ‘undefined‘) { 408 skin_opacity = _obj.style.skin.opacity; 409 console.log(skin_opacity) 410 } 411 //上 412 skin_up_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_up, cubeGeometry, 4); 413 //下 414 skin_down_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_down, cubeGeometry, 6); 415 //前 416 skin_fore_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_fore, cubeGeometry, 0); 417 //后 418 skin_behind_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_behind, cubeGeometry, 2); 419 //左 420 skin_left_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_left, cubeGeometry, 8); 421 //右 422 skin_right_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_right, cubeGeometry, 10); 423 } 424 var cubeMaterialArray = []; 425 cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_fore_obj)); 426 cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_behind_obj)); 427 cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_up_obj)); 428 cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_down_obj)); 429 cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_right_obj)); 430 cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_left_obj)); 431 var cubeMaterials = new THREE.MeshFaceMaterial(cubeMaterialArray); 432 cube = new THREE.Mesh(cubeGeometry, cubeMaterials); 433 cube.castShadow = true; 434 cube.receiveShadow = true; 435 cube.uuid = _obj.uuid; 436 cube.name = _obj.name; 437 cube.position.set(_x, _y, _z); 438 if (_obj.rotation != null && typeof (_obj.rotation) != ‘undefined‘ && _obj.rotation.length > 0) { 439 $.each(_obj.rotation, function (index, rotation_obj) { 440 switch (rotation_obj.direction) { 441 case ‘x‘: 442 cube.rotateX(rotation_obj.degree); 443 break; 444 case ‘y‘: 445 cube.rotateY(rotation_obj.degree); 446 break; 447 case ‘z‘: 448 cube.rotateZ(rotation_obj.degree); 449 break; 450 case ‘arb‘: 451 cube.rotateOnAxis(new THREE.Vector3(rotation_obj.degree[0], rotation_obj.degree[1], rotation_obj.degree[2]), rotation_obj.degree[3]); 452 break; 453 } 454 }); 455 } 456 457 return cube; 458 } 459 //创建二维平面-长方形 460 msj3D.prototype.createPlaneGeometry = function (_this,_obj) { 461 //options={ 462 // width:0, 463 // height:0, 464 // pic:"", 465 // transparent:true, 466 // opacity:1 467 // blending:false, 468 //position: { x:,y:,z:}, 469 //rotation: { x:,y:,z:}, 470 //} 471 472 var options = _obj; 473 if (typeof options.pic == "string") {//传入的材质是图片路径,使用 textureloader加载图片作为材质 474 var loader = new THREE.TextureLoader(); 475 loader.setCrossOrigin(this.crossOrigin); 476 var texture = loader.load(options.pic, function () { }, undefined, function () { }); 477 } else { 478 var texture = new THREE.CanvasTexture(options.pic) 479 } 480 var MaterParam = {//材质的参数 481 map: texture, 482 overdraw: true, 483 side: THREE.FrontSide, 484 // blending: THREE.AdditiveBlending, 485 transparent: options.transparent, 486 //needsUpdate:true, 487 //premultipliedAlpha: true, 488 opacity: options.opacity 489 } 490 if (options.blending) { 491 MaterParam.blending = THREE.AdditiveBlending//使用饱和度叠加渲染 492 } 493 var plane = new THREE.Mesh( 494 new THREE.PlaneGeometry(options.width, options.height, 1, 1), 495 new THREE.MeshBasicMaterial(MaterParam) 496 ); 497 plane.position.x = options.position.x; 498 plane.position.y = options.position.y; 499 plane.position.z = options.position.z; 500 plane.rotation.x = options.rotation.x; 501 plane.rotation.y = options.rotation.y; 502 plane.rotation.z = options.rotation.z; 503 return plane; 504 } 505 //创建空柜子 506 msj3D.prototype.createEmptyCabinet = function (_this, _obj) { 507 /* 参数demo 508 { 509 show:true, 510 name: ‘test‘, 511 uuid: ‘test‘, 512 rotation: [{ direction: ‘y‘, degree: 0.25*Math.PI}],//旋转 uuid:‘‘, 513 objType: ‘emptyCabinet‘, 514 transparent:true, 515 size:{length:50,width:60,height:200, thick:2}, 516 position: { x: -220, y: 105, z: -150 }, 517 doors: { 518 doorType:‘lr‘,// ud门 lr左右门 519 doorSize:[1], 520 skins:[ { 521 skinColor: 0x333333, 522 skin_fore: { 523 imgurl: "../datacenterdemo/res/rack_door_back.jpg", 524 }, 525 skin_behind: { 526 imgurl: "../datacenterdemo/res/rack_front_door.jpg", 527 } 528 }] 529 }, 530 skin:{ 531 skinColor: 0xdddddd, 532 533 skin:{ 534 skinColor: 0xdddddd, 535 skin_up: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" }, 536 skin_down: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" }, 537 skin_fore: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" }, 538 skin_behind: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" }, 539 skin_left: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" }, 540 skin_right: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" }, 541 } 542 543 } 544 } 545 */ 546 var _this = msj3DObj; 547 //创建五个面 548 //上 549 var upobj= { 550 show: true, 551 uuid: "", 552 name: ‘‘, 553 objType: ‘cube‘, 554 length: _obj.size.length+1, 555 width: _obj.size.width , 556 height: _obj.size.thick + 1, 557 x: _obj.position.x+1, 558 y: _obj.position.y+(_obj.size.height/2-_obj.size.thick/2), 559 z:_obj.position.z, 560 style: { 561 skinColor: _obj.skin.skinColor, 562 skin: _obj.skin.skin_up.skin 563 } 564 } 565 var upcube = _this.createCube(_this, upobj); 566 //左 567 var leftobj = { 568 show: true, 569 uuid: "", 570 name: ‘‘, 571 objType: ‘cube‘, 572 length: _obj.size.length, 573 width: _obj.size.thick, 574 height: _obj.size.height, 575 x: 0, 576 y: -(_obj.size.height / 2 - _obj.size.thick / 2), 577 z: 0 - (_obj.size.width / 2 - _obj.size.thick / 2) - 1, 578 style: { 579 skinColor: _obj.skin.skinColor, 580 skin: _obj.skin.skin_left.skin 581 } 582 } 583 var leftcube = _this.createCube(_this, leftobj); 584 var Cabinet = _this.mergeModel(_this, ‘+‘, upcube, leftcube); 585 //右 586 var Rightobj = { 587 show: true, 588 uuid: "", 589 name: ‘‘, 590 objType: ‘cube‘, 591 length: _obj.size.length, 592 width: _obj.size.thick, 593 height: _obj.size.height, 594 x: 0, 595 y: -(_obj.size.height / 2 - _obj.size.thick / 2), 596 z: (_obj.size.width / 2 - _obj.size.thick / 2)+1, 597 style: { 598 skinColor: _obj.skin.skinColor, 599 skin: _obj.skin.skin_right.skin 600 } 601 } 602 var Rightcube = _this.createCube(_this, Rightobj); 603 Cabinet = _this.mergeModel(_this, ‘+‘, Cabinet, Rightcube); 604 //后 605 var Behidobj = { 606 show: true, 607 uuid: "", 608 name: ‘‘, 609 objType: ‘cube‘, 610 length: _obj.size.thick, 611 width: _obj.size.width, 612 height: _obj.size.height, 613 x: (_obj.size.length / 2 - _obj.size.thick / 2)+1, 614 y: -(_obj.size.height / 2 - _obj.size.thick / 2), 615 z:0, 616 style: { 617 skinColor: _obj.skin.skinColor, 618 skin: _obj.skin.skin_behind.skin 619 } 620 } 621 var Behindcube = _this.createCube(_this, Behidobj); 622 Cabinet = _this.mergeModel(_this, ‘+‘, Cabinet, Behindcube); 623 //下 624 var Downobj = { 625 show: true, 626 uuid: "", 627 name: ‘‘, 628 objType: ‘cube‘, 629 length: _obj.size.length+1, 630 width: _obj.size.width, 631 height: _obj.size.thick, 632 x:-1, 633 y: -(_obj.size.height- _obj.size.thick)-1, 634 z: 0, 635 style: { 636 skinColor: _obj.skin.skinColor, 637 skin: _obj.skin.skin_down.skin 638 } 639 } 640 var Downcube = _this.createCube(_this, Downobj); 641 Cabinet = _this.mergeModel(_this, ‘+‘, Cabinet, Downcube); 642 643 var tempobj = new THREE.Object3D(); 644 tempobj.add(Cabinet); 645 tempobj.name = _obj.name; 646 tempobj.uuid = _obj.uuid; 647 Cabinet.name = _obj.shellname, 648 _this.objects.push(Cabinet); 649 tempobj.position = Cabinet.position; 650 //门 651 if (_obj.doors != null && typeof (_obj.doors) != ‘undefined‘) { 652 var doors = _obj.doors; 653 if (doors.skins.length == 1) {//单门 654 var singledoorobj = { 655 show: true, 656 uuid:"", 657 name: _obj.doors.doorname[0], 658 objType: ‘cube‘, 659 length: _obj.size.thick, 660 width: _obj.size.width, 661 height: _obj.size.height, 662 x: _obj.position.x - _obj.size.length / 2 - _obj.size.thick / 2, 663 y: _obj.position.y, 664 z: _obj.position.z, 665 style: { 666 skinColor: _obj.doors.skins[0].skinColor, 667 skin: _obj.doors.skins[0] 668 } 669 } 670 var singledoorcube = _this.createCube(_this, singledoorobj); 671 _this.objects.push(singledoorcube); 672 tempobj.add(singledoorcube); 673 } else if (doors.skins.length > 1) {//多门 674 675 676 } 677 678 } 679 680 if (_obj.rotation != null && typeof (_obj.rotation) != ‘undefined‘ && _obj.rotation.length > 0) { 681 $.each(_obj.rotation, function (index, rotation_obj) { 682 switch (rotation_obj.direction) { 683 case ‘x‘: 684 tempobj.rotateX(rotation_obj.degree); 685 break; 686 case ‘y‘: 687 tempobj.rotateY(rotation_obj.degree); 688 break; 689 case ‘z‘: 690 tempobj.rotateZ(rotation_obj.degree); 691 break; 692 case ‘arb‘: 693 tempobj.rotateOnAxis(new THREE.Vector3(rotation_obj.degree[0], rotation_obj.degree[1], rotation_obj.degree[2]), rotation_obj.degree[3]); 694 break; 695 } 696 }); 697 } 698 return tempobj; 699 } 700 //创建玻璃 701 msj3D.prototype.createGlasses = function (_this, _obj) { 702 var _this = msj3DObj; 703 var tmpobj = _this.createPlaneGeometry(_this, _obj); 704 _this.addObject(tmpobj); 705 _obj.rotation.y = Math.PI + _obj.rotation.y; 706 var tmpobj2 = _this.createPlaneGeometry(_this, _obj); 707 _this.addObject(tmpobj2); 708 } 709 //创建皮肤 710 msj3D.prototype.createSkin = function (flength,fwidth,_obj) { 711 var imgwidth = 128,imgheight=128; 712 if (_obj.width != null&& typeof (_obj.width) != ‘undefined‘) { 713 imgwidth = _obj.width; 714 } 715 if (_obj.height != null && typeof (_obj.height) != ‘undefined‘) { 716 imgheight = _obj.height; 717 } 718 var texture = new THREE.TextureLoader().load(_obj.imgurl); 719 var _repeat = false; 720 if (_obj.repeatx != null && typeof (_obj.repeatx) != ‘undefined‘ && _obj.repeatx==true) { 721 texture.wrapS = THREE.RepeatWrapping; 722 _repeat = true; 723 } 724 if (_obj.repeaty != null && typeof (_obj.repeaty) != ‘undefined‘ && _obj.repeaty == true) { 725 texture.wrapT = THREE.RepeatWrapping; 726 _repeat = true; 727 } 728 if (_repeat) { 729 texture.repeat.set(flength / imgheight, fwidth / imgheight); 730 } 731 return texture; 732 } 733 //创建皮肤参数对象 734 msj3D.prototype.createSkinOptionOnj = function (_this, flength, fwidth, _obj, _cube, _cubefacenub) { 735 if (_this.commonFunc.hasObj(_obj)) { 736 if (_this.commonFunc.hasObj(_obj.imgurl)) { 737 return { 738 map: _this.createSkin(flength, fwidth, _obj),transparent:true 739 } 740 } else { 741 if (_this.commonFunc.hasObj(_obj.skinColor)) { 742 _cube.faces[_cubefacenub].color.setHex(_obj.skinColor); 743 _cube.faces[_cubefacenub + 1].color.setHex(_obj.skinColor); 744 } 745 return { 746 vertexColors: THREE.FaceColors 747 } 748 } 749 } else { 750 return { 751 vertexColors: THREE.FaceColors 752 } 753 } 754 } 755 //通用方法 756 msj3D.prototype.commonFunc={ 757 //判断对象 758 hasObj: function (_obj) { 759 if (_obj != null && typeof (_obj) != ‘undefined‘) { 760 return true; 761 }else{ 762 return false; 763 } 764 }, 765 //查找对象 766 findObject: function (_objname) { 767 var _this = msj3DObj; 768 console.log(‘findObject‘); 769 var findedobj = null; 770 $.each(_this.objects, function (index,_obj) { 771 if (_obj.name != null && _obj.name != ‘‘) { 772 if (_obj.name == _objname) { 773 findedobj = _obj; 774 return true; 775 } 776 } 777 }); 778 return findedobj; 779 }, 780 //复制对象 781 cloneObj: function (_objname, newparam) { 782 /*newparam 783 { 784 show: true, 785 uuid: 786 copyfrom: ‘cabinet1_1‘, 787 name: 788 childrenname:[] 789 objType: ‘cloneObj‘, 790 position:{x:y:z:}//相对复制品的 791 scale:{x:1,y:1,z:1} 792 rotation: [{ direction: ‘y‘, degree: 0.25*Math.PI}],//旋转 uuid:‘‘, 793 } 794 */ 795 var _this = msj3DObj; 796 var fobj = _this.commonFunc.findObject(_objname); 797 var newobj = newobj = fobj.clone(); 798 if (newobj.children != null && newobj.children.length > 1) { 799 $.each(newobj.children, function (index, obj) { 800 obj.name = newparam.childrenname[index]; 801 _this.objects.push(obj); 802 }); 803 } 804 //位置 805 if (_this.commonFunc.hasObj(newparam.position)) { 806 newobj.position.x = newparam.position.x; 807 newobj.position.y = newparam.position.y; 808 newobj.position.z = newparam.position.z; 809 } 810 //大小 811 if (_this.commonFunc.hasObj(newparam.scale)) { 812 newobj.scale.x = newparam.scale.x; 813 newobj.scale.y = newparam.scale.y; 814 newobj.scale.z = newparam.scale.z; 815 } 816 //角度 817 if (_this.commonFunc.hasObj(newparam.rotation)) { 818 $.each(newparam.rotation, function (index, rotation_obj) { 819 switch (rotation_obj.direction) { 820 case ‘x‘: 821 newobj.rotateX(rotation_obj.degree); 822 break; 823 case ‘y‘: 824 newobj.rotateY(rotation_obj.degree); 825 break; 826 case ‘z‘: 827 newobj.rotateZ(rotation_obj.degree); 828 break; 829 case ‘arb‘: 830 newobj.rotateOnAxis(new THREE.Vector3(rotation_obj.degree[0], rotation_obj.degree[1], rotation_obj.degree[2]), rotation_obj.degree[3]); 831 break; 832 } 833 }); 834 } 835 newobj.name = newparam.name; 836 newobj.uuid = newparam.uuid; 837 return newobj; 838 }, 839 //设置表皮颜色 840 setSkinColor: function (_objname, _color) { 841 var _this = msj3DObj; 842 var _obj = _this.commonFunc.findObject(_objname); 843 if (_this.commonFunc.hasObj(_obj.material.emissive)) { 844 _obj.material.emissive.setHex(_color); 845 } else if (_this.commonFunc.hasObj(_obj.material.materials)) { 846 if (_obj.material.materials.length > 0) { 847 $.each(_obj.material.materials, function (index,obj) { 848 obj.emissive.setHex(_color); 849 }); 850 } 851 } 852 }, 853 //添加图片标识 854 addIdentification: function (_objname, _obj) { 855 /* 856 { 857 name:‘test‘, 858 size:{x:20,y:20}, 859 position:{x:0,y:100,z:0}, 860 imgurl: ‘../datacenterdemo/res/connection.png‘ 861 } 862 */ 863 var _this = msj3DObj; 864 var _fobj = _this.commonFunc.findObject(_objname); 865 var loader = new THREE.TextureLoader(); 866 var texture = loader.load(_obj.imgurl, function () { }, undefined, function () { }); 867 var spriteMaterial = new THREE.SpriteMaterial({ map: texture, useScreenCoordinates: false }); 868 var sprite = new THREE.Sprite(spriteMaterial); 869 sprite.name = _obj.name; 870 sprite.position.x = _fobj.position.x + _obj.position.x; 871 sprite.position.y = _fobj.position.y + _obj.position.y; 872 sprite.position.z = _fobj.position.z + _obj.position.z; 873 if (_this.commonFunc.hasObj(_obj.size)) { 874 sprite.scale.set(_obj.size.x, _obj.size.y); 875 } else { 876 sprite.scale.set(1,1); 877 } 878 _this.addObject(sprite); 879 }, 880 //添加文字 881 makeTextSprite: function (_objname, parameters) 882 { 883 var _this = msj3DObj; 884 var _fobj = _this.commonFunc.findObject(_objname); 885 if ( parameters === undefined ) parameters = {}; 886 var fontface = parameters.hasOwnProperty("fontface") ? parameters["fontface"] : "Arial"; 887 var fontsize = parameters.hasOwnProperty("fontsize") ? parameters["fontsize"] : 18; 888 var borderThickness = parameters.hasOwnProperty("borderThickness") ? parameters["borderThickness"] : 4; 889 var textColor = parameters.hasOwnProperty("textColor") ?parameters["textColor"] : { r:0, g:0, b:0, a:1.0 }; 890 var message = parameters.hasOwnProperty("message") ? parameters["message"] : "helloMsj3D"; 891 var x = parameters.hasOwnProperty("position") ? parameters["position"].x : 0; 892 var y = parameters.hasOwnProperty("position") ? parameters["position"].y : 0; 893 var z = parameters.hasOwnProperty("position") ? parameters["position"].z : 0; 894 var canvas = document.createElement(‘canvas‘); 895 var context = canvas.getContext(‘2d‘); 896 context.font = "Bold " + fontsize + "px " + fontface; 897 var metrics = context.measureText( message ); 898 var textWidth = metrics.width; 899 context.lineWidth = borderThickness; 900 context.fillStyle = "rgba("+textColor.r+", "+textColor.g+", "+textColor.b+", 1.0)"; 901 context.fillText(message, borderThickness, fontsize + borderThickness); 902 var texture = new THREE.Texture(canvas) 903 texture.needsUpdate = true; 904 var spriteMaterial = new THREE.SpriteMaterial( { map: texture, useScreenCoordinates: false } ); 905 var sprite = new THREE.Sprite(spriteMaterial); 906 sprite.position.x =_fobj.position.x + x; 907 sprite.position.y = _fobj.position.y + y; 908 sprite.position.z = _fobj.position.z + z; 909 sprite.name = parameters.name; 910 sprite.scale.set(0.5 * fontsize, 0.25 * fontsize, 0.75 * fontsize); 911 _this.addObject(sprite); 912 } 913 } 914 msj3D.prototype.loadObj = function (_obj) { 915 var jsloader = new THREE.JSONLoader(); 916 jsloader.load("test.json", 917 function (geometry, materials) { 918 var model = new THREE.SkinnedMesh(geometry, new THREE.MeshFaceMaterial(materials)); 919 model.name = ‘test‘; 920 model.scale.x = 10; 921 model.scale.y = 7; 922 model.scale.z = 10; 923 model.position.x = -300; 924 model.position.y = 50; 925 model.position.z = 300; 926 _this.addObject(model); 927 }); 928 } 929 930 //添加按钮 931 msj3D.prototype.addBtns = function (_btnobjs) { 932 var _this = msj3DObj; 933 if (_btnobjs != null && _btnobjs.length > 0) { 934 $("#" + _this.fId).after(‘<div id="toolbar" class="toolbar" ></div>‘); 935 $.each(_btnobjs, function (index,_obj) { 936 $("#toolbar").append(‘ <img src="‘ + _obj.btnimg + ‘" title="‘ + _obj.btnTitle + ‘" id="‘ + _obj.btnid + ‘" />‘); 937 $("#" + _obj.btnid).on("click", _obj.event); 938 }); 939 } 940 } 941 942 /* 943 *事件部分 944 */ 945 946 //鼠标按下事件 947 var dbclick =0; 948 msj3D.prototype.onDocumentMouseDown = function (event) { 949 dbclick++; 950 var _this = msj3DObj; 951 setTimeout(function () { dbclick =0}, 500); 952 event.preventDefault(); 953 if (dbclick >= 2) { 954 _this.raycaster.setFromCamera(_this.mouseClick, _this.camera); 955 var intersects = _this.raycaster.intersectObjects(_this.objects); 956 if (intersects.length > 0) { 957 _this.controls.enabled = false; 958 _this.SELECTED = intersects[0].object; 959 if (_this.eventList != null && _this.eventList.dbclick != null && _this.eventList.dbclick.length > 0) { 960 $.each(_this.eventList.dbclick, function (index, _obj) { 961 if ("string" == typeof (_obj.obj_name)) { 962 if (_obj.obj_name == _this.SELECTED.name) { 963 _obj.obj_event(_this.SELECTED); 964 } 965 } else if (_obj.findObject!=null||‘function‘ == typeof (_obj.findObject)) { 966 if (_obj.findObject(_this.SELECTED.name)) { 967 _obj.obj_event(_this.SELECTED); 968 } 969 } 970 }); 971 } 972 _this.controls.enabled = true; 973 } 974 } 975 } 976 977 978 msj3D.prototype.onDocumentMouseMove = function (event) { 979 event.preventDefault(); 980 var _this = msj3DObj; 981 _this.mouseClick.x = (event.clientX / _this.width) * 2 - 1; 982 _this.mouseClick.y = -(event.clientY / _this.height) * 2 + 1; 983 _this.raycaster.setFromCamera(_this.mouseClick, _this.camera); 984 985 } 986 987 988 msj3D.prototype.addTestObj = function () { 989 990 var _this = msj3DObj; 991 992 //var jsloader = new THREE.JSONLoader(); 993 //jsloader.load("test.json", 994 // function (geometry, materials) { 995 // var model = new THREE.SkinnedMesh(geometry, new THREE.MeshFaceMaterial(materials)); 996 // model.name = ‘test‘; 997 // model.scale.x = 10; 998 // model.scale.y = 7; 999 // model.scale.z = 10; 1000 // model.position.x = -300; 1001 // model.position.y = 50; 1002 // model.position.z = 300; 1003 // _this.addObject(model); 1004 // }); 1005 //var plane = 1006 //_this.createPlaneGeometry(_this, { 1007 // width: 100, 1008 // height: 200, 1009 // pic: "../datacenterdemo/res/glass.png", 1010 // transparent: true, 1011 // opacity: 1, 1012 // position: { x: 0, y: 100, z: -200 }, 1013 // rotation: { x: 0, y: 0*Math.PI, z: 0 }, 1014 // blending: false 1015 //}); 1016 }
三、库也封装好了 下面就直接用呗
这个也存成一个文件,姑且先叫做data.js吧
var msjstation; function threeStart() { var initOption = { antialias: true, showHelpGrid: false, clearCoolr: 0x112233 }; msjstation = new msj3D(); var Aobjects = { objects: [ //地板 { show: true, uuid: "", name: ‘floor‘, objType: ‘floor‘, length: 2000, width: 1600, height: 10, rotation: [{ direction: ‘x‘, degree: 0 }],//旋转 表示x方向0度 arb表示任意参数值[x,y,z,angle] x: 0, y: 0, z: 0, style: { skinColor: 0x8ac9e2, skin: { skin_up: { skinColor: 0x98750f, imgurl: "../datacenterdemo/res/floor.jpg", repeatx: true, repeaty: true, width: 128, height: 128 }, skin_down: { skinColor: 0x8ac9e2, }, skin_fore: { skinColor: 0x8ac9e2, } } } }, //墙体 { show: true, uuid: "", name: ‘wall‘, objType: ‘wall‘, thick: 20, length: 100, height: 240, wallData: [ {//wall1 uuid: "", name: ‘wall1‘, thick: 20, height: 240, skin: { skin_up: { skinColor: 0xdddddd, }, skin_down: { skinColor: 0xdddddd, }, skin_fore: { skinColor: 0xb0cee0, }, skin_behind: { skinColor: 0xb0cee0, }, skin_left: { skinColor: 0xdeeeee, }, skin_right: { skinColor: 0xb0cee0, } }, startDot: { x: -500, y: 120, z: -350 }, endDot: { x: 500, y: 120, z: -350 }, rotation: [{ direction: ‘x‘, degree: 0 }],//旋转 表示x方向0度 arb表示任意参数值[x,y,z,angle] childrens: [ { op: ‘-‘, show: true, uuid: "", name: ‘doorhole‘, objType: ‘doorhole‘, thick: 20, height: 220, startDot: { x: -410, y: 110, z: -350 }, endDot: { x: -190, y: 110, z: -350 }, skin: { skin_up: { skinColor: 0xffdddd, }, skin_down: { skinColor: 0xdddddd, }, skin_fore: { skinColor: 0xffdddd, }, skin_behind: { skinColor: 0xffdddd, }, skin_left: { skinColor: 0xffdddd, }, skin_right: { skinColor: 0xffdddd, } }, }, { op: ‘-‘, show: true, uuid: "", name: ‘windowHole‘, objType: ‘windowHole‘, thick: 20, height: 160, startDot: { x: -50, y: 130, z: -350 }, endDot: { x: 450, y: 130, z: -350 } }, { show: true, name: ‘windowCaseBottom‘, uuid: "", objType: ‘cube‘, thick: 30, height: 10, startDot: { x: -50, y: 50, z: -350 }, endDot: { x: 450, y: 50, z: -350 }, skin: { skin_up: { skinColor: 0xc0dee0, }, skin_down: { skinColor: 0xc0dee0, }, skin_fore: { skinColor: 0xc0dee0, }, skin_behind: { skinColor: 0xc0dee0, }, skin_left: { skinColor: 0xd0eef0, }, skin_right: { skinColor: 0xd0eef0, } }, }, { show: true, uuid: "", name: ‘doorCaseRight‘, objType: ‘cube‘, thick: 24, height: 220, startDot: { x: -410, y: 110, z: -350 }, endDot: { x: -405, y: 110, z: -350 }, skin: { skin_up: { skinColor: 0xc0dee0, }, skin_down: { skinColor: 0xc0dee0, }, skin_fore: { skinColor: 0xc0dee0, }, skin_behind: { skinColor: 0xc0dee0, }, skin_left: { skinColor: 0xd0eef0, }, skin_right: { skinColor: 0xd0eef0, } }, }, { show: true, name: ‘doorCaseLeft‘, uuid: "", objType: ‘cube‘, thick: 24, height: 220, startDot: { x: -190, y: 110, z: -350 }, endDot: { x: -195, y: 110, z: -350 }, skin: { skin_up: { skinColor: 0xc0dee0, }, skin_down: { skinColor: 0xc0dee0, }, skin_fore: { skinColor: 0xc0dee0, }, skin_behind: { skinColor: 0xc0dee0, }, skin_left: { skinColor: 0xd0eef0, }, skin_right: { skinColor: 0xd0eef0, } }, }, { show: true, name: ‘doorCaseTop‘, uuid: "", objType: ‘cube‘, thick: 24, height: 5, startDot: { x: -190, y: 220, z: -350 }, endDot: { x: -410, y: 220, z: -350 }, skin: { skin_up: { skinColor: 0xc0dee0, }, skin_down: { skinColor: 0xc0dee0, }, skin_fore: { skinColor: 0xc0dee0, }, skin_behind: { skinColor: 0xc0dee0, }, skin_left: { skinColor: 0xd0eef0, }, skin_right: { skinColor: 0xd0eef0, } }, }, { show: true, name: ‘doorCaseBottom‘, uuid: "", objType: ‘cube‘, thick: 24, height: 5, startDot: { x: -190, y: 5, z: -350 }, endDot: { x: -410, y: 5, z: -350 }, skin: { skin_up: { skinColor: 0xc0dee0, }, skin_down: { skinColor: 0xc0dee0, }, skin_fore: { skinColor: 0xc0dee0, }, skin_behind: { skinColor: 0xc0dee0, }, skin_left: { skinColor: 0xd0eef0, }, skin_right: { skinColor: 0xd0eef0, } }, }, { show: true, name: ‘doorLeft‘, uuid: "", objType: ‘cube‘, thick: 4, height: 210, startDot: { x: -196, y: 112, z: -350 }, endDot: { x: -300, y: 112, z: -350 }, skin: { opacity: 0.1, skin_up: { skinColor: 0x51443e, }, skin_down: { skinColor: 0x51443e, }, skin_fore: { skinColor: 0x51443e, }, skin_behind: { skinColor: 0x51443e, }, skin_left: { skinColor: 0x51443e, imgurl: "../datacenterdemo/res/door_left.png", }, skin_right: { skinColor: 0x51443e, imgurl: "../datacenterdemo/res/door_right.png", } }, }, { show: true, name: ‘doorRight‘, uuid: "", objType: ‘cube‘, thick: 4, height: 210, startDot: { x: -300, y: 112, z: -350 }, endDot: { x: -404, y: 112, z: -350 }, skin: { opacity: 0.1, skin_up: { skinColor: 0x51443e, }, skin_down: { skinColor: 0x51443e, }, skin_fore: { skinColor: 0x51443e, }, skin_behind: { skinColor: 0x51443e, }, skin_left: { skinColor: 0x51443e, imgurl: "../datacenterdemo/res/door_right.png", }, skin_right: { skinColor: 0x51443e, imgurl: "../datacenterdemo/res/door_left.png", } }, }, { show: true, name: ‘doorControl‘, uuid: "", objType: ‘cube‘, thick: 10, height: 40, startDot: { x: -120, y: 160, z: -365 }, endDot: { x: -160, y: 160, z: -365 }, skin: { opacity: 0.1, skin_up: { skinColor: 0x333333, }, skin_down: { skinColor: 0x333333, }, skin_fore: { skinColor: 0x333333, }, skin_behind: { skinColor: 0x333333, }, skin_left: { skinColor: 0x333333, imgurl: "../datacenterdemo/res/doorControl.jpg", }, skin_right: { skinColor: 0x333333, } }, }, ] }, {//wall2 uuid: "", name: ‘wall2‘, thick: 20, height: 240, skin: { skin_up: { skinColor: 0xdddddd, }, skin_down: { skinColor: 0xdddddd, }, skin_fore: { skinColor: 0xb0cee0, }, skin_behind: { skinColor: 0xb0cee0, }, skin_left: { skinColor: 0xb0cee0, }, skin_right: { skinColor: 0xdeeeee, } }, startDot: { x: -500, y: 120, z: 450 }, endDot: { x: 500, y: 120, z: 450 }, }, {//wall3 uuid: "", name: ‘wall3‘, thick: 20, height: 240, skin: { skin_up: { skinColor: 0xdddddd, }, skin_down: { skinColor: 0xdddddd, }, skin_fore: { skinColor: 0xb0cee0, }, skin_behind: { skinColor: 0xdeeeee, }, skin_left: { skinColor: 0xb0cee0, }, skin_right: { skinColor: 0xb0cee0, } }, startDot: { x: 490, y: 120, z: -355 }, endDot: { x: 490, y: 120, z: 455 }, }, {//wall4 uuid: "", name: ‘wall4‘, thick: 20, height: 240, skin: { skin_up: { skinColor: 0xdddddd, }, skin_down: { skinColor: 0xdddddd, }, skin_fore: { skinColor: 0xdeeeee, }, skin_behind: { skinColor: 0xb0cee0, }, skin_left: { skinColor: 0xb0cee0, }, skin_right: { skinColor: 0xb0cee0, } }, startDot: { x: -490, y: 120, z: -355 }, endDot: { x: -490, y: 120, z: 455 }, } ], style: { skinColor: 0x8ac9e2 } }, //玻璃 { show: true, name: ‘windowGlass1‘, uuid: "", objType: ‘glasses‘, width: 500, height: 160, pic: "../datacenterdemo/res/glass.png", transparent: true, opacity: 1, position: { x: 200, y: 130, z: -350 }, rotation: { x: 0, y: 0 * Math.PI, z: 0 }, blending: false, }, //贴海报 { show: true, name: ‘messagePanel‘, uuid: "", objType: ‘plane‘, width: 100, height: 160, pic: "../datacenterdemo/res/message.jpg", transparent: true, opacity: 1, position: { x:-250, y: 150, z: 439 }, rotation: { x: 0, y: Math.PI, z: 0 }, blending: false, }, //空调 { show: true, uuid: "", name: ‘aircondition‘, objType: ‘cube‘, length: 60, width: 80, height: 220, rotation: [{ direction: ‘y‘, degree: 0.3*Math.PI}],//旋转 表示x方向0度 arb表示任意参数值[x,y,z,angle] x: -420, y: 110, z: 370, style: { skinColor: 0xfefefe, skin: { skin_fore: { imgurl: "../datacenterdemo/res/aircondition.jpg", }, } } }, //电视机 { show: true, uuid: "", name: ‘television‘, objType: ‘cube‘, length: 10, width: 180, height: 120, rotation: [{ direction: ‘x‘, degree:0}],//旋转 表示x方向0度 arb表示任意参数值[x,y,z,angle] x: -480, y: 150, z: 0, style: { skinColor: 0x555555, skin: { skin_fore: { imgurl: "../datacenterdemo/res/tv.jpg", }, } } }, //机柜1-1 --原型 { show:true, name: ‘cabinet1_1‘, shellname:‘cabinet1_1_shell‘, uuid: ‘‘, // rotation: [{ direction: ‘y‘, degree: 0.25*Math.PI}],//旋转 uuid:‘‘, objType: ‘emptyCabinet‘, transparent:true, size:{length:66,width:70,height:200, thick:2}, position: { x:300, y: 105, z: -180 }, doors: { doorType:‘lr‘,// ud上下门 lr左右门 单门可以缺省 doorSize: [1], doorname: [‘cabinet1_1_door_01‘], skins:[ { skinColor: 0x333333, skin_fore: { imgurl: "../datacenterdemo/res/rack_door_back.jpg", }, skin_behind: { imgurl: "../datacenterdemo/res/rack_front_door.jpg", } }] }, skin:{ skinColor: 0xff0000, skin_up: { skin:{ skinColor: 0xff0000, skin_up: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" }, skin_down: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" }, skin_fore: { skinColor: 0xff0000, imgurl: "../datacenterdemo/res/rack_door_back.jpg" }, skin_behind: { skinColor: 0xff0000, imgurl: "../datacenterdemo/res/rack_door_back.jpg" }, skin_left: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" }, skin_right: { imgurl: "../datacenterdemo/res/rack_door_back.jpg" }, } }, skin_down: { skin: { skinColor: 0x333333, } }, skin_left: { skin: { skinColor: 0x333333, } }, skin_right: { skin: { skinColor: 0x333333, } }, skin_behind: { skin: { skinColor: 0x333333, } } } }, //主机1 { show: true, uuid: "", name: ‘equipment_card_1‘, objType: ‘cube‘, length: 60, width: 65, height: 10, x: -100, y: 105, z: -180, style: { skinColor: 0xff0000, skin: { skin_up: { skinColor: 0xff0000, imgurl: "../datacenterdemo/res/rack_inside.jpg", }, skin_down: { skinColor: 0xff0000, imgurl: "../datacenterdemo/res/rack_inside.jpg", }, skin_fore: { skinColor: 0xff0000, imgurl: "../datacenterdemo/res/rack_inside.jpg", }, skin_behind: { skinColor: 0xff0000, imgurl: "../datacenterdemo/res/server2.jpg", }, skin_left: { skinColor: 0xff0000, imgurl: "../datacenterdemo/res/rack_inside.jpg", }, skin_right: { skinColor: 0xff0000, imgurl: "../datacenterdemo/res/rack_inside.jpg", } } } }, //主机2 { show: true, uuid: "", name: ‘equipment_card_2‘, objType: ‘cube‘, length: 60, width: 65, height: 20, x: -100, y: 120, z: -180, style: { skinColor: 0x92630b, skin: { skin_up: { skinColor: 0x92630b, imgurl: "../datacenterdemo/res/rack_inside.jpg", }, skin_down: { skinColor: 0x92630b, imgurl: "../datacenterdemo/res/rack_inside.jpg", }, skin_fore: { skinColor: 0x92630b, imgurl: "../datacenterdemo/res/rack_inside.jpg", }, skin_behind: { skinColor: 0x92630b, imgurl: "../datacenterdemo/res/server2.jpg", }, skin_left: { skinColor: 0x92630b, imgurl: "../datacenterdemo/res/rack_inside.jpg", }, skin_right: { skinColor: 0x92630b, imgurl: "../datacenterdemo/res/rack_inside.jpg", } } } }, //主机3 { show: true, uuid: "", name: ‘equipment_card_3‘, objType: ‘cube‘, length: 60, width: 65, height: 30, x: -100, y: 145, z: -180, style: { skinColor: 0x92630b, skin: { skin_up: { skinColor: 0x92630b, imgurl: "../datacenterdemo/res/rack_inside.jpg", }, skin_down: { skinColor: 0x92630b, imgurl: "../datacenterdemo/res/rack_inside.jpg", }, skin_fore: { skinColor: 0x92630b, imgurl: "../datacenterdemo/res/rack_inside.jpg", }, skin_behind: { skinColor: 0x92630b, imgurl: "../datacenterdemo/res/server3.jpg", }, skin_left: { skinColor: 0x92630b, imgurl: "../datacenterdemo/res/rack_inside.jpg", }, skin_right: { skinColor: 0x92630b, imgurl: "../datacenterdemo/res/rack_inside.jpg", } } } }, ], events: { dbclick: [ { obj_name: "doorRight", obj_uuid: "", obj_event: function (_obj) { openRightDoor(_obj, function () { }); } }, { obj_name: "doorLeft", obj_uuid: "", obj_event: function (_obj) { var doorstate = "close"; var tempobj = null; if (_obj.doorState != null && typeof (_obj.doorState) != ‘undefined‘) { doorstate = _obj.doorState; tempobj = _obj.parent; } else { console.log("add parent"); var _objparent = _obj.parent; tempobj = new THREE.Object3D(); tempobj.position.set(_obj.position.x + _obj.geometry.parameters.width / 2, _obj.position.y, _obj.position.z); _obj.position.set(-_obj.geometry.parameters.width / 2, 0, 0); tempobj.add(_obj); _objparent.add(tempobj); } _obj.doorState = (doorstate == "close" ? "open" : "close"); new TWEEN.Tween(tempobj.rotation).to({ y: (doorstate == "close" ? -0.25 * 2 * Math.PI : 0 * 2 * Math.PI) }, 10000).easing(TWEEN.Easing.Elastic.Out).start(); } }, { obj_name: "cabinetdoor3_1", obj_uuid: "", obj_event: function (_obj) { opcabinetdoor(_obj); } }, { findObject:function(_objname){//查找某一类符合名称的对象 if (_objname.indexOf("cabinet") >= 0 && _objname.indexOf("door") >= 0) { return true; } else { return false; } }, obj_uuid: "", obj_event: function (_obj) { opcabinetdoor(_obj); } }, { findObject: function (_objname) {//查找某一类符合名称的对象 if (_objname.indexOf("equipment") >= 0 && _objname.indexOf("card") >= 0) { return true; } else { return false; } }, obj_uuid: "", obj_event: function (_obj) { var cardstate = "in"; if (_obj.cardstate != null && typeof (_obj.cardstate) != ‘undefined‘) { cardstate = _obj.cardstate; } else { _obj.cardstate = "out"; } new TWEEN.Tween(_obj.position).to({ x: (cardstate == "in" ? _obj.position.x - 50 : _obj.position.x + 50), }, 1000).onComplete(function () { _obj.cardstate = cardstate == "in" ? "out" : "in"; }).start(); } } ], mouseDown: { }, mouseUp: { }, mouseMove: { } }, btns: [ { btnid: "btn_reset", btnTitle: "场景复位", btnimg: "../datacenterdemo/res/reset.png", event: function () { $(‘#canvas-frame‘).empty(); msjstation = null; msj3DObj = null; msjstation = new msj3D(); msjstation.initmsj3D(‘canvas-frame‘, initOption, Aobjects); msjstation.start(); //var mainCamera = msj3DObj.commonFunc.findObject("mainCamera");//主摄像机 //new TWEEN.Tween(mainCamera.position).to({ // x: 0, y: 1000, z: -1800, //}, 1000).start(); //mainCamera.lookAt({ x: 0, y: 0, z: 0 }); } }, { btnid: "btn_connection", btnTitle: "走线管理", btnimg: "../datacenterdemo/res/connection.png", event: function () { } }, { btnid: "btn_usage", btnTitle: "机柜利用率", btnimg: "../datacenterdemo/res/usage.png", event: function () { } }, { btnid: "btn_edit", btnTitle: "拖拽机柜", btnimg: "../datacenterdemo/res/edit.png", event: function () { } }, { btnid: "btn_alarm", btnTitle: "告警巡航", btnimg: "../datacenterdemo/res/alarm.png", event: function () { var mainCamera = msj3DObj.commonFunc.findObject("mainCamera");//主摄像机 var doorRight = msj3DObj.commonFunc.findObject("doorRight"); mainCamera.lookAt(doorRight.position); new TWEEN.Tween(mainCamera.position).to({ x:-300, y:200, z:-700, }, 5000).onComplete(function () { openRightDoor(msj3DObj.commonFunc.findObject("doorRight"), function () { var cabinet3_1 = msj3DObj.commonFunc.findObject("cabinet3_1"); mainCamera.lookAt(cabinet3_1.position); new TWEEN.Tween(mainCamera.position).to({ x: -300, y: 150, z: -200, }, 5000).onComplete(function () { mainCamera.lookAt(cabinet3_1.position); }).start(); }); }).start(); } }, ] } //复制机柜 for (var i = 1; i <=3;i++){ for (var j = 1; j <=6; j++) { if (i != 1 || j != 1) { Aobjects.objects.push({ show: true, copyfrom: ‘cabinet1_1‘, name: ‘cabinet‘+i+‘_‘+j, childrenname: [‘cabinet‘ + i + ‘_‘ + j + ‘_shell‘, ‘cabinet‘ + i + ‘_‘ + j + ‘_door_01‘], uuid: ‘‘, objType: ‘cloneObj‘, position: { x:-(i-1)*200, y:0 , z:(j-1)*100 }, scale: { x: 1, y: 1, z: 1 } }); } } } msjstation.initmsj3D(‘canvas-frame‘, initOption, Aobjects); msjstation.start(); } function opcabinetdoor(_obj) { var doorstate = "close"; var tempobj = null; if (_obj.doorState != null && typeof (_obj.doorState) != ‘undefined‘) { doorstate = _obj.doorState; tempobj = _obj.parent; } else { console.log("add parent"); var _objparent = _obj.parent; tempobj = new THREE.Object3D(); tempobj.position.set(_obj.position.x, _obj.position.y, _obj.position.z + _obj.geometry.parameters.depth / 2); _obj.position.set(0, 0, -_obj.geometry.parameters.depth / 2); tempobj.add(_obj); _objparent.add(tempobj); } _obj.doorState = (doorstate == "close" ? "open" : "close"); new TWEEN.Tween(tempobj.rotation).to({ y: (doorstate == "close" ? 0.25 * 2 * Math.PI : 0 * 2 * Math.PI) }, 1000).start(); } function openRightDoor(_obj,func) { var doorstate = "close"; var tempobj = null; if (_obj.doorState != null && typeof (_obj.doorState) != ‘undefined‘) { doorstate = _obj.doorState; tempobj = _obj.parent; } else { console.log("add parent"); var _objparent = _obj.parent; tempobj = new THREE.Object3D(); tempobj.position.set(_obj.position.x - _obj.geometry.parameters.width / 2, _obj.position.y, _obj.position.z); _obj.position.set(_obj.geometry.parameters.width / 2, 0, 0); tempobj.add(_obj); _objparent.add(tempobj); } _obj.doorState = (doorstate == "close" ? "open" : "close"); new TWEEN.Tween(tempobj.rotation).to({ y: (doorstate == "close" ? 0.25 * 2 * Math.PI : 0 * 2 * Math.PI) }, 10000).easing(TWEEN.Easing.Elastic.Out).onComplete(func()).start(); }
该封的都封好了
然后就创建一个页面直接运行呗,那就简单了,直接在onload事件里面调用一下 就行了。
<!DOCTYPE html>
<html>
<head>
<title></title>
<link href="../webglJS/msj3D.css" rel="stylesheet" />
<meta charset="utf-8" />
<script src="../webglJS/jquery-2.2.2.js"></script>
<script src="../webglJS/three.min.js"></script>
<script src="../webglJS/stats.min.js"></script>
<script src="../webglJS/OrbitControls.js"></script>
<script src="../webglJS/ThreeBSP.js"></script>
<script src="../webglJS/Tween.js"></script>
<script src="../myStationTest/msj3D.js"></script>
<script src="data.js"></script>
</head>
<body onload="threeStart();">
<div id="canvas-frame" class="canvas_frame"></div>
</body>
</html>
好了,先写这么多,嘻嘻,其实也没写啥东西 全是贴码
后面再加博文讲解吧。
本人也是three.js的初学者,不正的地方,还望大牛前辈指点。
交流邮箱:531844326@qq.com