在工业方面,有很多3D模型用于制作模型。在一个大环境中,构建了无数相同或不同的模型。构建对于程序员来说非常重要,也是相当头疼的事情。我们使用HT来帮助您解决很多问题。官网可以找到无数的例子http://hightopo.com/demos/ind...本文的demo地址:http://hightopo.com/guide/gui...这次我们的例子是提取一个这些例子中的一小部分思路,作为大家的分析,看一下这个实现的例子效果图:这个例子使用了HT中的树组件ht.widget.TreeView和加载OBJ的ht.Default.loadObj函数HT中的格式文件用于加载图中的两辆摩托车。我们使用代码从头分析这个例子的部分。首先观察这个例子的界面展示,你会发现界面由左右两部分组成,右边由上下两部分组成。这种拆分方式在HT中有很好的解决方案,可以充分利用ht.widget。SplitView可以用来对界面进行分层,ht.widget.BorderPane也可以用来将界面分为上中下。这里我们使用这两种方法,因为它是一个例子:dataModel=newht.DataModel();//datamodelg3d=newht.graph3d.Graph3dView(dataModel);//3dcomponenttoolbar=newht.widget.Toolbar(item);//toolbarborderPane=newht.widget.BorderPane();//面板组件borderPane.setTopView(toolbar);//toolbar放在上borderPane.setCenterView(g3d);//g3d放在中间部分treeView=newht.widget.TreeView(数据模型);//树组件mainSplit=newht.widget.SplitView(treeView,borderPane,'h',0.2);//工具栏中的item也遵循HT设置规则的拆分组件,item是一个数组,数组中的每个元素都是工具栏的一部分。在这个例子中,toolbar只有2个元素,也足够具有代表性:item=[{label:'Editable',type:'check',action:function(){g3d.setEditable(this.selected);}},{id:'size',label:'Size',slider:{width:120,min:1,max:60,value:1,thickness:1,onValueChanged:function(){if(rawS3){varvalue=this.getValue();dataModel.each(function(data){if(datainstanceofht.Node){data.s3(rawS3[0]*value,rawS3[1]*value,rawS3[2]*value);data.s({'note.scale':value/20,'note.t3':[0,-value,value]});}});}}];我们可以通过设置工具栏中的item元素来设置对象的格式类型,其中type可以设置为check、toggle和radio,分别代表复选框、切换按钮和单选按钮。这里我们设置Editable是否可以编辑为复选框。可以通过控制该元素来设置是否可编辑。下面的拉杆也是HT中封装的ht.Slider绑定OBJ对象的大小。OBJ的大小是通过控制滑块来控制的。详见HTforWeb工具栏组件手册。然后把最外层的组件添加到底层的div中,给没看过我文章的同学说明一下,所有HT组件的根层都是一个div组件,可以通过组件的getView函数获取。默认和自定义的交互时间监听一般都加在这个div中(getView().addEventListener(type,func,false)),渲染层一般由canvas提供,用户可以直接在根div和canvas层设置css样式,或者在根div中添加新的HTML组件作为canvas的兄弟组件一起渲染。详情请参考《HTforWeb入门手册》。然后使用ht.widget.loadObj函数将OBJ格式文件导入到模型中:ht.Default.loadObj('obj/scooter.obj','obj/scooter.mtl',{//Theindivisiblemotorcyclecubeonthe左:真,中:真,shape3d:'滑板车',finishFunc:函数(modelMap,array,rawS3){window.rawS3=rawS3;if(modelMap){varnode=newht.Node();node.setName('AllinONE');node.s({'shape3d':'scooter','wf.visible':'selected','note':'OneNode','note.face':'center','note.position':7,'note.background':'blue','note.autorotate':'y'});node.s3(rawS3);node.p3(-300,0,0);数据模型。添加(节点);}检查加载();}});ht.Default.loadObj函数有三个参数,objUrlOBJ文件路径,mtlUrlMTL文件路径,paramsJSON结构参数,parmas参数可以设置ht.Default.parseObj(text,mtlMap,params)第三个参数的控制信息,也就是说ht.Default.parseObj函数中的第三个参数第三个参数params可以使用ht.Default.loadObj函数的控制信息,增加了sync和finishFunc参数。finishFUnc参数是加载后回调处理的函数,参数为modelMap、array和rawS3,finishFunc无所不能!详情请参考HTforWebOBJ手册本例中有两个机动摩托车模型,一个是整体模型,不能拆分,一个是可以拆分成零件的模型。接下来看看OBJ文件中的模型如何分割:ht.Default.loadObj('obj/scooter.obj','obj/scooter.mtl',{//右侧可分割的摩托车立方体:true,center:true,finishFunc:function(modelMap,array,rawS3){if(modelMap){varlastNode=null,firstNode=null,parentNode=newht.Data();parentNode.setName('SeparateScooter');dataModel.add(parentNode);for(varnameinmodelMap){varmodel=modelMap[name];varshape3d='scooter:'+name;ht.Default.setShape3dModel(shape3d,model);varnode=newht.Node();node.setName(name);node.setParent(parentNode);node.s({'shape3d':shape3d,'wf.visible':'已选择'});node.setHost(lastNode);最后一个节点=节点;如果(!firstNode){firstNode=节点;}node.s3(rawS3);dataModel.add(节点);}如果(最后一个节点){第一个节点。设置主机(lastNode);firstNode.p3(300,0,0);firstNode.s({'note':'很多节点托管在一起','note.face':'center','note.position':7,'note.background':'blue'});}}checkLoaded();}});我们可以通过modelMap获取ht.Default.parseObj函数解析的返回值,通常是obj格式的文件解析后返回的map结构的json对象,每种材质对应一个模型信息,参考HT有关详细信息,请参见WebOBJ手册。我们使用ht.Default.parseObj函数来解析获取各个材质的模型信息。通过遍历整个模型,我们得到单独的模型信息并命名,这样我们就可以显示每个模型的名称,控制模型的每个部分。上述代码第45行出现的checkLoaded函数是一个方便控制树组件展开合并的函数。在工业等各个领域,我们经常用到“树”的概念,所以也用这个例子来说明:functioncheckLoaded(){loadTask--;if(loadTask===0){treeView.expandAll();树视图.selectAll();ht.Default.startAnim({action:function(t){toolbar.v('size',50*t);}});}}因为我们在“树”部分只使用了两个主要节点,Allinone和SeperateScooter,所以我们定义loadTask变量值为2,上面代码的意思是如果两个模型都加载完后,展开树组件treeView并全选,然后用代码控制toolbar中的数值为50*t来调整模型的大小。对于树组件treeView,HT封装了很多helper组件,让开发更快。例如本例中使用的setSortFunc函数就是用来设置排序的;setCheckMode函数用于设置检查模式。check会想到多选框,这里HT通过设置setCheckMode函数来设置多选框,这个函数的参数可以是:null:默认值,不启用check选择模式default:默认选中模式的选择模式,即点击选中或取消选中只会影响当前点击的数据对象children:该选中模式会同时影响被点击的数据对象及其子对象descendant:该选中模式会同时影响被点击的数据对象andallitschildrenDescendantobjectsall:这种检查模式将影响被点击的数据对象,以及它的所有父对象和后代对象。如果还是不明白,可以试试把这个函数注释掉,就可以清楚的明白它是干什么的了。或者查看HTforWeb树组件手册。以上就是今天的例子。实际开发的例子会更复杂,逻辑也会更多,但是通过HT,一切都变得如此简单!
