Cet article partage principalement avec vous le diagramme de structure de topologie de réseau 3D de HTML5 WebG. Nous présenterons la structure de topologie de réseau 3D en détail avec des images et des textes, dans l'espoir d'aider tout le monde.
De nos jours, les modèles 3D sont utilisés dans de nombreux domaines différents. Ils sont utilisés dans l'industrie médicale pour fabriquer des modèles précis d'organes ; dans l'industrie cinématographique, ils sont utilisés dans des personnages animés, des objets et des films réalistes ; dans l'industrie du jeu vidéo, ils sont utilisés comme actifs dans les ordinateurs et les jeux vidéo et dans la science ; ils sont utilisés comme modèles précis de composés chimiques. L'industrie de l'architecture les utilise pour démontrer des bâtiments proposés ou des expressions paysagères ; la communauté des ingénieurs les utilise pour concevoir de nouveaux équipements, véhicules, structures et autres applications ; Le domaine a commencé à construire des modèles géologiques tridimensionnels, et les modèles 3D sont souvent animés, par exemple dans les longs métrages et les jeux informatiques et vidéo. Ils peuvent être utilisés au sein d’un outil de modélisation 3D ou seuls. Afin de créer facilement des animations, certaines données supplémentaires sont généralement ajoutées au modèle. Par exemple, certains modèles 3D d'humains ou d'animaux disposent d'un système squelettique complet, de sorte que le mouvement semble plus réaliste et puisse être contrôlé via les articulations. et des os.
Tout cela nous fait penser à nous, développeurs front-end, que ce serait formidable si nous pouvions obtenir des effets 3D sans apprendre unity3d ou d'autres outils de développement de jeux, et pouvoir contrôler avec précision le mouvement ou la direction avec du code. . . J'ai donc utilisé le composant 3D de HT For Web pour implémenter un petit exemple, utilisant la plupart des fonctions du composant 3D de HT. Le but de cet exemple est d'avoir une bonne compréhension du composant 3D et d'essayer de l'intégrer. un exemple pour que d'autres puissent s'y référer si nécessaire.
Jetons d'abord un coup d'œil aux rendus de l'implémentation globale :
Utilisez HT for Web pour créer trois couches à partir du modèle 3D existant La plaque inférieure n'est pas le problème. Le problème est de savoir comment placer les "composants de l'ordinateur" et de l'armoire sur le premier calque de l'image ? J'ai téléchargé le fichier au format obj sur Internet, puis j'ai utilisé la fonction ht.Default.loadObj(objUrl, mtlUrl, params) dans HT pour y charger le modèle. Pour la partie params, veuillez vous référer à http://www. .hightopo.com/guide..., le code est le suivant :
ht.Default.loadObj('obj/机柜组件1.obj', 'obj/机柜组件1.mtl', { //加载 obj 文件 cube: true, //是否将模型缩放到单位1的尺寸范围内,默认为false center: true, //模型是否居中,默认为false,设置为true则会移动模型位置使其内容居中 shape3d: 'box', //如果指定了shape3d名称,则HT将自动将加载解析后的所有材质模型构建成数组的方式,以该名称进行注册 finishFunc: function(modelMap, array, rawS3){ //用于加载后的回调处理 if(modelMap){ device2 = createNode('box', floor1); //创建一个节点,在第一层“地板”上 device2.p3([x1-120, y1+13, z1+60]); //设置这个节点坐标 device2.s3(rawS3); //设置这个节点大小 createEdge(device1, device2); //创建连线 device3 = createNode('box', floor1); device3.s3(rawS3); device3.p3([x1+120, y1+13, z1+60]); createEdge(device1, device3); } } });
Les trois paramètres de la fonction finishiFunc sont définis comme suit :
modelMap : appelez ht.Default.parseObj La valeur de retour après l'analyse, si le chargement ou l'analyse échoue, la valeur de retour sera vide
array : un tableau composé de tous les modèles matériels
rawS3 : Contient la taille originale de tous les modèles
Généralement dans les applications pratiques, nous définirons la taille de la primitive à la taille originale du modèle.
Il y a un "avertissement" rouge au-dessus de "Ordinateur" indiquant qu'une rotation tridimensionnelle est possible, qui repose sur la fonction ht.Default.setShape3dModel (HT pour Web Modeling Manual http://www.hightopo.com /guide.. . Modèle 3D, en ht, il existe de nombreuses fonctions de modélisation encapsulées, les plus basiques sont la sphère, le cylindre, le cube, etc. Ici, j'utilise la méthode de construction d'anneau createRingModel pour générer l'anneau le plus externe de "warning". la partie supérieure du point d'exclamation est la sphère construite à l'aide de createSmoothSphereModel, et la partie inférieure du point d'exclamation est le cylindre construit à l'aide de createSmoothCylinderModel au début, j'ai directement utilisé la fonction encapsulée dans le modèle 3D, donc je ne savais pas quels étaient les paramètres. utilisé dans la fonction. À quoi sert-il, et je ne comprends pas comment le modèle 3D est composé, j'ai donc relu les "Bases du modèle" précédentes et j'ai réalisé que le modèle 3D original utilise le plus une surface. La surface de base est la surface triangulaire, puis les surfaces complexes le sont également. Elle est formée de plusieurs surfaces triangulaires puis tournée autour d'un axe spécifique. Bien sûr, cet axe est décidé par vous. Différents axes peuvent générer différentes formes pour des paramètres tels que. couleur et style, veuillez vous référer au manuel de style HT for Web (http://www.hightopo.com/guide...) Quant à la façon de faire pivoter ce modèle 3D, ht encapsule la méthode addScheduleTask(Task) que j'ai appelée ht dans. la troisième couche de Task. Une fonction de rotation encapsulée setRotation est utilisée pour définir l'ordre et la direction de rotation, et spécifier l'objet à faire pivoter. Ce qui suit est une méthode pour personnaliser le modèle 3D de « avertissement » (Remarque : parce que le modèle. dans cet exemple est une combinaison personnalisée, si vous souhaitez la définir. La couleur du modèle global doit utiliser l'attribut de style "all.blend") :
function createAlarm(device, formPane) { var ringModel = ht.Default.createRingModel([ 8, 1, 10, 1, 10, -1, 8, -1, 8, 1 ], null, null, false, false, 100);//根据xy平面的曲线,环绕一周形成3D模型。 var sphereModel = ht.Default.createSmoothSphereModel(8, 8, 0, Math.PI*2, 0, Math.PI, 2);//构建光滑球体模型 var cylinderModel = ht.Default.createSmoothCylinderModel(8, true, true, 1, 2, 0, Math.PI*2, 8);//构建光滑圆柱体模型 var alarmArr = [//组合模型 由三个模型ringModel、sphereModel、cylinderModel组合而成 { shape3d: ringModel,//定义模型类型 r3: [Math.PI/2, 0, 0],//设置旋转角度 color: {//设置模型颜色 func: 'style@all.blend',//数据绑定style样式中的all.blend属性,可通过data.s()获取和设置这个属性 } },{ shape3d: sphereModel, t3: [0, 4, 0], color: { func: 'style@all.blend', } },{ shape3d: cylinderModel, t3: [0, -3, 0], color: { func: 'style@all.blend', } } ]; ht.Default.setShape3dModel('alarm', {//注册自定义3D模型 shape3d: alarmArr }); var alarmTip = createNode('alarm', device);//创建shape3d为alarm的节点 alarmTip.s3([2, 2, 2]);//设置节点大小 alarmTip.p3(device.p3()[0], device.p3()[1]+60, device.p3()[2]); alarmTip.s('all.blend', 'red');//改变此属性可改变模型的颜色,因为模型创建的时候已经数据绑定了 return alarmTip; }
Ensuite, voyons comment créer cela " "alarme" nœud "flash". Je lie directement cette animation au nœud. De cette façon, l'animation peut être contrôlée directement via le nœud, donc lorsque nous créons le modèle d'alarme ci-dessus, nous pouvons directement lier l'animation au nœud :
if(formPane){ alarmNode.scaleFunc = function() {//设置大小变化动画 var size = alarmNode.s3();//获取节点的大小 if (size[0] === 2 && size[1] === 2 && size[2] === 2) alarmNode.s3([1, 1, 1]); else alarmNode.s3([2, 2, 2]); alarmNode.scaleTimer = setTimeout(alarmNode.scaleFunc, formPane.v('scaleInterval'));//设置动画 } alarmNode.blinkFunc = function(){//设置闪烁的动画 var color = alarmNode.s('all.blend');//获取节点的style样式 if (color === 'red') alarmNode.s({'all.blend': 'yellow'});//如果节点颜色为红色,那么设置为黄色 else alarmNode.s({'all.blend': 'red'}); alarmNode.blinkTimer = setTimeout(alarmNode.blinkFunc, formPane.v('blinkInterval')); } alarmNode.rotateFunc = function() {//设置旋转动画 alarmNode.setRotation(alarmNode.getRotation() + Math.PI/20);//获取节点当前的旋转角度,在这个旋转角度之上添加 Math.PI/20 个角度 alarmNode.rotateTimer = setTimeout(alarmNode.rotateFunc, formPane.v('rotInterval')); } }
J'ai paramétré l'animation ci-dessus pour pouvoir passer par le panneau de formulaire. Propriétés pour contrôler la vitesse de clignotement des nœuds, l'animation des nœuds clignotants, etc. Parlons principalement de l'implémentation de cette fonction sur le formulaire :
formPane.addRow([//向form表单面板上添加一行元素 { checkBox: {//复选框 label: 'Enable Blink',//复选框对应的文本内容 selected: true,//设置选中复选框 onValueChanged: function(){//复选框值变化时回调的函数 var data = dataModel.getDataByTag('colorAlarm');//通过tag标签获取节点 if (this.getValue()) {//获取复选框当前值true/false data.blinkTimer = setTimeout(data.blinkFunc, formPane.v('blinkInterval'));//直接通过设置节点的blinkTimer来设置动画 } else { clearTimeout(data.blinkTimer);//清除动画 } } } }, { id: 'blinkInterval',//form可以通过getValue(简写为v)来获取这个item的值 slider: {//设置了该属性后HT将根据属性值自动构建ht.widget.Slider对象,并保存在element属性上 min: 0,//滑动条最小值 max: 1000,//滑动条最大值 step: 50,//滑动条步进 value: 500,//当前滑动条的值 } } ], [0.1, 0.1]);//设置这行的两个item元素的宽度小于1的值为比例
Parlons enfin du flux de boules sur le pipeline 3D , cette fonction est effectivement très pratique, et l'effet est vraiment bon, j'aimerais la partager avec vous~.
首先,创建一条连线连接起始节点和结束节点并设置这个连线的样式,用 ht.Edge 可以将连线吸附在起始节点和结束节点上,这样移动这两个节点中的任意一个节点连线都会跟着节点移动的位置变化,非常方便:
var polyline = new ht.Edge(source, target);//创建连线 dataModel.add(polyline);//将连线添加进数据容器中 polyline.s({ 'edge.width': 5,//连线宽度 'edge.type': 'points',//连线类型 为points时连线走向将由edge.points属性决定,用于绘制折线 'edge.points': [//可设置类型为ht.List的{x:100, y:100}格式的点对象数组,当edge.type为points时起作用 {x: source.getPosition3d()[0]+200, y: source.getPosition3d()[2], e: source.getPosition3d()[1]}, {x: target.getPosition3d()[0]+400, y: target.getPosition3d()[2], e: target.getPosition3d()[1]} ], 'edge.segments': [1, 4],//用于描述点连接样式,数组元素为整型值 'shape3d': 'cylinder',//圆柱 'shape3d.color': 'rgba(242, 200, 40, 0.4)', 'shape3d.resolution': 30,//微分段数,可以决定曲线的平滑度 'edge.source.t3': [20, 0, 0],//连线source端偏移,[tx, ty, tz]格式,默认为空 'edge.target.t3': [20, 0, 0]//连线target端偏移,[tx, ty, tz]格式,默认为空 });
因为我们在创建连线的时候设置的 points 仅为曲线上的两个点,所以如果要获取曲线目前形成的点,是缺少 source 和 target 两个点的,我们重新设置一个数组,将这两个点添加进去,后面获取曲线上所有点时会用上:
var list = new ht.List(); list.push({x: source.getPosition3d()[0], y: source.getPosition3d()[2], e: source.getPosition3d()[1]});//向数组中添加source点 polyline.s('edge.points').each(function(item){//添加style属性中已设置的两个点 list.push(item); }); list.push({x: target.getPosition3d()[0], y: target.getPosition3d()[2], e: target.getPosition3d()[1]});//添加target点
然后创建一个在管线上滑动的小球节点,这是仅是设置节点,真正添加进数据容器 dataModel 中需要设置完小球的坐标时再添加,如果没有给节点设置位置就将节点添加进数据容器中,节点的初始位置就是 3D 场景的正中心 [0, 0, 0] 的位置。小球滑动的动画代码如下:
var ball = new ht.Node();//创建小球节点 ball.s({//设置小球节点的样式 'shape3d': 'sphere',//设置小球的3d模型为球形 'shape3d.color': 'rgba(40, 90, 240, 0.4)'//设置3d模型的颜色 }); var delta = 10, flag = 0; setInterval(function(){ flag++; var length = (polyline.a('total') || 0) % polyline.a('length') + delta;//小球当前走过的曲线长度 var cache = ht.Default.getLineCacheInfo(list, polyline.s('edge.segments'));//获取曲线上的点的信息 var lineLength = ht.Default.getLineLength(cache);//获取曲线的总长度 polyline.a('length', lineLength - 50);//因为我设置了edge的t3(相当于2d中的offset),所以线段长度实际没有那么长 var offset = ht.Default.getLineOffset(cache, length);//曲线根据曲线上点的信息的偏移量 ball.setPosition3d(offset.point.x + 10, offset.point.y, offset.point.z);//设置节点的坐标 polyline.a('total', length); if(flag === 1) dataModel.add(ball);//这时候节点已经有了坐标了,可以添加进数据容器中了 }, 10);
我们还可以看到第二层上有两个特殊的多边形“平行四边形”和“梯形”,平行四边形是靠 createParallelogramModel 模型函数,这个函数比较简单,createExtrusionModel(array, segments, top, bottom, resolution, repeatUVLength, tall, elevation),array 是你要形成的图形的坐标点,这边只是针对于 xz 轴上画的平面图形,segments 指的是如何连接这几个坐标点,可参考 HT for Web 形状手册(http://hightopo.com/guide/gui...),top 和 bottom 就是让你选择是否有顶部或者底部,resolution 微分段数,我们描绘一段曲线的时候可能只要确认几个个别的点然后在每两个点之间的连线上把它分成多个段,这样这条线段就会变得平滑,ht 为了用户能够轻松操作这些线段,就封装了这一个参数,repeatUVLength 默认为空,设置值后顶部和底部的贴图将根据制定长度值进行重复,tall 模型的高度,默认为 5,elevation 模型中心的 y 轴位置,默认值为 0,设置这个值可以使 xz 上的平面绕着 y 轴旋转。
底层的一个环形的效果是通过一个算法来实现的,环形得确认这个环形上有多少个元素,然后算每两个之间的角度,在通过 sin、cos 来计算每一个元素的位置,得出了如下代码:
names = ['设备2', '设备3', '设备4', '设备5', '设备6', '设备7', '设备8', '设备9']; names.forEach(function(name, index) { x = 400, y = 200, angle = 45, r = 120; x = x3 + Math.sin((2 * Math.PI / 360) * angle * index) * r; y = z3 + Math.cos((2 * Math.PI / 360) * angle * index) * r; device = createRect([x, y3 + 15, y], [w * 0.1, 15, h * 0.1], '', '', floor3); createEdge(device5, device); });
相关推荐:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!