前言
效果图
代码生成
创建场景
dm = new ht.DataModel();//数据模型(http://hightopo.com/guide/guide/core/datamodel/ht-datamodel-guide.html)
g3d = new ht.graph3d.Graph3dView(dm);//3D 场景组件(http://hightopo.com/guide/guide/core/3d/ht-3d-guide.html)
palette = new ht.widget.Palette();//面板组件(http://hightopo.com/guide/guide/plugin/palette/ht-palette-guide.html)
splitView = new ht.widget.SplitView(palette, g3d, 'h', 0.2);//分割组件,第三个参数为分割的方式 h 为左右分,v 为上下分;第四个参数为分割比例,大于 1 的值为绝对宽度,小于 1 则为比例
splitView.addToDOM();//将分割组件添加进 body 体中
addToDOM = function(){
var self = this,
view = self.getView(),//获取组件的底层 div
style = view.style;
document.body.appendChild(view);//将组件底层div添加进body中
style.left = '0';//ht 默认将所有的组件的position都设置为absolute绝对定位
style.right = '0';
style.top = '0';
style.bottom = '0';
window.addEventListener('resize', function () { self.iv(); }, false);//窗口大小改变事件,调用刷新函数
}
node = new ht.Node();
node.s3(1000, 1, 1000);//设置节点的大小
node.r3(0, 0, Math.PI/4);//设置节点旋转 这个旋转的角度是有学问的,跟下面我们要设置的拖拽放置的位置有关系
node.s('3d.movable', false);//设置节点在3d上不可移动 因为这个节点只是一个参照物,建议是不允许移动
dm.add(node);//将节点添加进数据容器中
左侧内容构建
function initPalette() {//加载palette面板组件中的图元
var arrNode = ['displayDevice', 'cabinetRelative', 'deskChair', 'temperature', 'indoors', 'monitor','others'];
var nameArr = ['展示设施', '机柜相关', '桌椅储物', '温度控制', '室内', '视频监控', '其他'];//arrNode中的index与nameArr中的一一对应
for (var i = 0; i < arrNode.length; i++) {
var name = nameArr[i];
var vName = arrNode[i];
arrNode[i] = new ht.Group();//palette面板是将图元都分在“组”里面,然后向“组”中添加图元即可
palette.dm().add(arrNode[i]);//向palette面板组件中添加group图元
arrNode[i].setExpanded(true);//设置分组为打开的状态
arrNode[i].setName(name);//设置组的名字 显示在分组上
var imageArr = [];
switch(i){//根据不同的分组设置每个分组中不同的图元
case 0:
imageArr = ['models/机房/展示设施/大屏.png'];
break;
case 1:
imageArr = ['models/机房/机柜相关/配电箱.png', 'models/机房/机柜相关/室外天线.png', 'models/机房/机柜相关/机柜1.png',
'models/机房/机柜相关/机柜2.png', 'models/机房/机柜相关/机柜3.png', 'models/机房/机柜相关/机柜4.png',
'models/机房/机柜相关/电池柜.png'];
break;
case 2:
imageArr = ['models/机房/桌椅储物/储物柜.png', 'models/机房/桌椅储物/桌子.png', 'models/机房/桌椅储物/椅子.png'];
break;
case 3:
imageArr = ['models/机房/温度控制/空调精简.png', 'models/机房/消防设施/消防设备.png'];
break;
case 4:
imageArr = ['models/室内/办公桌简易.png', 'models/室内/书.png', 'models/室内/办公桌镜像.png', 'models/室内/办公椅.png'];
break;
case 5:
imageArr = ['models/机房/视频监控/摄像头方.png', 'models/机房/视频监控/对讲维护摄像头.png', 'models/机房/视频监控/微型摄像头.png'];
break;
default:
imageArr = ['models/其他/信号塔.png'];
break;
}
setPalNode(imageArr, arrNode[i]);//创建palette上节点及设置名称、显示图片、父子关系
}
}
function setPalNode(imageArr, arr) {
for (var j = 0; j < imageArr.length; j++) {
var imageName = imageArr[j];
var jsonUrl = imageName.slice(0, imageName.lastIndexOf('.')) + '.json';//shape3d中的 json 路径
var name = imageName.slice(imageName.lastIndexOf('/')+1, imageName.lastIndexOf('.')); //取最后一个/和.之间的字符串用来设置节点名称
var url = imageName.slice(imageName.indexOf('/')+1, imageName.lastIndexOf('.'));//取第一个/和最后一个.之间的字符串用来设置拖拽生成模型obj文件的路径
createNode(name, imageName, arr, url, jsonUrl);//创建节点,这个节点是显示在palette面板上
}
}
function createNode(name, image, parent, urlName, jsonUrl) {//创建palette面板组件上的节点
var node = new ht.Node();
palette.dm().add(node);
node.setName(name);//设置节点名称 palette面板上显示的文字也是通过这个属性设置名称
node.setImage(image);//设置节点的图片
node.setParent(parent);//设置父亲节点
node.s({
'draggable': true,//设置节点可拖拽
'image.stretch': 'centerUniform',//设置节点图片的绘制方式
'label': ''//设置节点的label为空,这样即使设置了name也不会显示在3d中的模型下方
});
node.a('urlName', urlName);//a设置用户自定义属性
node.a('jsonUrl', jsonUrl);
return node;
}
拖拽功能
function dragAndDrop() {//拖拽功能
g3d.getView().addEventListener("dragover", function(e) {//拖拽事件
e.dataTransfer.dropEffect = "copy";
handleOver(e);
});
g3d.getView().addEventListener("drop", function(e) {//放开鼠标事件
handleDrop(e);
});
}
function handleOver(e) {
e.preventDefault();//取消事件的默认动作。
}
function handleDrop(e) {//鼠标放开时
e.preventDefault();//取消事件的默认动作。
var paletteNode = palette.dm().sm().ld();//获取palette面板中最后选中的节点
if (paletteNode) {
loadObjFunc('assets/objs/' + paletteNode.a('urlName') + '.obj', 'assets/objs/' + paletteNode.a('urlName') + '.mtl',
paletteNode.a('jsonUrl'), g3d.getHitPosition(e, [0, 0, 0], [-1, 1, 0]));//加载obj模型
}
}
加载模型
function loadObjFunc(objUrl, mtlUrl, jsonUrl, p3) {//加载obj模型
var node = new ht.Node();
var shape3d = jsonUrl.slice(jsonUrl.lastIndexOf('/')+1, jsonUrl.lastIndexOf('.'));
ht.Default.loadObj(objUrl, mtlUrl, {//HT 通过 loadObj 函数来加载 obj 模型
cube: true,//是否将模型缩放到单位1的尺寸范围内,默认为false
center: true,//模型是否居中,默认为false,设置为true则会移动模型位置使其内容居中
shape3d: shape3d,//如果指定了shape3d名称,则HT将自动将加载解析后的所有材质模型构建成数组的方式,以该名称进行注册
finishFunc: function(modelMap, array, rawS3) {//用于加载后的回调处理
if (modelMap) {
node.s({//设置节点样式
'shape3d': jsonUrl,//jsonUrl 为 obj 模型的 json 文件路径
'label': ''//设置label为空,label的优先级高于name,所以即使设置了name,节点的下方也不会显示name名称
});
g3d.dm().add(node);//将节点添加进数据容器中
node.s3(rawS3);//设置节点大小 rawS3 模型的原始尺寸
node.p3(p3);//设置节点的三维坐标
node.setName(shape3d);//设置节点名称
node.setElevation(node.s3()[1]/2);//控制Node图元中心位置所在3D坐标系的y轴位置
g3d.sm().ss(node);//设置选中当前节点
g3d.setFocus(node);//将焦点设置在当前节点上
return node;
}
}
});
}
总结