索引
HT for 3D Web提供了六面体、
shape3d上预定义的球体、圆柱体等多种常规三维模型,
ht.Shape类型可实现墙面、管道和多边形等三维模型效果,
本手册将介绍更灵活的自定义三维模型功能,以满足不同行业设备及不同环境场景的建模需求。
自定义3D模型具有以下优点:
3D模型3D模型数据Blender、3ds Max和Maya等第三方建模工具构建的模型,参见OBJ手册本手册介绍的部分扩展模型库的函数,由ht-modeling.js的建模扩展包提供。
3D模型是由最基础的三角形面拼接合成,例如1个矩形可以由2个三角形构成,1个立方体由6个面即12个三角形构成,
以此类推更复杂的模型可以由许多的小三角形组合合成。因此3D模型定义即为对构造模型的所有三角形的描述,
而每个三角形由三个顶点vertex构成,
每个顶点vertex由x,y,z三维空间坐标决定,HT采用右手螺旋定则来确定三个顶点构造三角形面的正面。
最简单的3D模型描述方式就是由一个顶点数组来描述,例如p1-p2-p3这三个点构成的三角形,
可用数组[p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, p3.x, p3.y, p3.z]来描述,更多三角形如下图所示:
以上这种描述方式格式简单较容易理解,但重复数据较多,例如上图中顶点1、2和3分别在T1、T2和T3的三角形定义中重复描述,
因此可采用顶点和三角形分离描述的方式,即用两个数组,一个数组描述顶点vertices,HT中简称vs,
一个数组描述三角形对应顶点的索引indices,HT中简称is。上图对于的索引描述方式如下:
从几何模型角度以上的定义已足够构建一个完整3D模型,界面呈现一般还需要定义颜色或贴图决定渲染效果,
采用贴图的渲染方式需要对每个顶点定义其对应的贴图位置信息,
UV Mapping参见六面体章节,
HT中简称为uv。如果模型只用普通颜色渲染,则可不定义该参数。
三维场景模型显示效果还取决于每个三角形面法线向量与光线的夹角,法线向量normal在HT的模型中以ns的简称代表,
一般HT可根据顶点自动计算ns信息,但有些模型为实现特殊的渲染效果,每个顶点可通过ns指定对应的法线向量值,
可参考Phong shading进行理解。
以下定义模型均采用在xzy轴大小为1范围内的立方体作为参考,[0,0,0]对应于图元的中心位置,
如果xzy轴的点坐标绝对值超过0.5则意味着超出图元size3d定义的大小。
通过ht.Default.setShape3dModel(name, model)函数,可注册自定义3D模型:
name为模型名称,如果名称与预定义的一样,则会替换预定义的模型。model为JSON类型对象,其具体属性参数定义如下,其中的bottom_*、top_*、from_*和to_*分别对应
shape3d.bottom.*、shape3d.top.*、shape3d.from.*和shape3d.to.*的控制参数。例如3D模型可以定义
top_*模型信息,但顶面是否显示由shape3d.top.visible参数控制,顶面显示颜色由shape3d.top.color参数控制,
顶面是否贴图由shape3d.top.image参数控制,如果模型没有定义top_*信息,则shape3d.top.*参数皆无意义。
vs:顶点坐标数组is:顶点索引数组uv:顶点贴图坐标数组ns:顶点法线向量数组bottom_vs:底面顶点坐标数组bottom_is:底面顶点索引数组bottom_uv:底面顶点贴图坐标数组bottom_ns:底面顶点法线向量数组top_vs:顶面顶点坐标数组top_is:顶面顶点索引数组top_uv:顶面顶点贴图坐标数组top_ns:顶面顶点法线向量数组from_vs:起始面顶点坐标数组from_is:起始面顶点索引数组from_uv:起始面顶点贴图坐标数组from_ns:起始面顶点法线向量数组to_vs:结束面顶点坐标数组to_is:结束面顶点索引数组to_uv:结束面顶点贴图坐标数组to_ns:结束面顶点法线向量数组综上所述,自定义模型的流程为:
3D模型的JSON数据结构信息对象JSON模型对象注册到系统中,ht.Default.setShape3dModel('dragon', dragonModel)node.setStyle('shape3d', 'dragon')类似2D图片不需要全局注册,可直接将内容设置的图元属性node.setImage('www.google.com/logo.png')的方式,3D也支持这种简化的方式,
将构建3D的JSON模型对象直接设置到图元属性:node.setStyle('shape3d', dragonModel),但这种方式对于DataModel序列化数据导出是不利的,
这种方式导致相同模型的图元重复输出3D模型信息,而且3D模型信息一般数据量很大,不建议与DataModel的整体模型信息一起导出,
我们一般视3D模型信息和图片信息同为外围资源信息,建议与DataModel数据模型信息分开存储管理。
自定义3D模型非常灵活强大,但对于复杂模型,手写顶点工作量和难度很高,为此HT抽象了几类模型,提供了函数API的便捷构建方式,
以下函数除createFrameModel如要引入ht-modeling.js扩展包外,其余都已由ht.js提供:
ht.Default.createBoxModel()构建六面体模型,该模型的六个面显示的颜色和贴图都将一样
ht.Default.createSphereModel(side, sideFrom, sideTo, from, to, resolution)构建球体模型
side:总边数sideFrom:起始边索引sideTo:结束边索引from:是否有起始面to:是否有结束面resolution:代表微分段数ht.Default.createSmoothSphereModel(hResolution, vResolution, hStart, hArc, vStart, vArc, radius)构建光滑球体模型
hResolution:水平方向微分段数vResolution:垂直方向微分段数hStart:水平方向起始角度,默认为0hArc:水平方向总弧度,默认为Math.PI*2vStart:垂直方向起始角度,默认为0vArc:垂直方向总弧度,默认为Math.PIradius:球体半径,默认为0.5ht.Default.createCylinderModel(side, sideFrom, sideTo, from, to, top, bottom)构建圆柱体模型
side:总边数sideFrom:起始边索引sideTo:结束边索引from:是否有起始面to:是否有结束面top:是否有顶部bottom:是否有底部ht.Default.createSmoothCylinderModel(resolution, top, bottom, topRadius, bottomRadius, start, arc, height)构建光滑圆柱体模型
resolution:圆柱微分段数top:是否有顶部bottom:是否有底部topRadius:顶部半径,默认为0.5bottomRadius:底部半径,默认为0.5start:起始角度,默认为0arc:总弧度,默认为Math.PI*2height:圆柱高度,默认为1ht.Default.createConeModel(side, sideFrom, sideTo, from, to, bottom)构建圆锥体模型
side:总边数sideFrom:起始边索引sideTo:结束边索引from:是否有起始面to:是否有结束面bottom:是否有底部ht.Default.createSmoothConeModel(bottom, resolution, start, arc, radius)构建光滑圆锥体模型
bottom:是否有底部resolution:微分段数start:起始角度,默认为0arc:总弧度,默认为Math.PI*2radius:底部半径,默认为0.5ht.Default.createTorusModel(side, sideFrom, sideTo, from, to, radius, resolution)构建圆环体模型
side:总边数sideFrom:起始边索引sideTo:结束边索引from:是否有起始面to:是否有结束面radius:圆环的管半径,默认值为0.17,可取值范围0~2.5resolution:截面圆形微分段数ht.Default.createSmoothTorusModel(radius, tubeRadius, hResolution, vResolution, start, arc)构建光滑圆环体模型
radius:圆环半径位置tubeRadius:截面圆形半径大小hResolution:圆环水平方向微分段数vResolution:截面圆形微分段数start:起始角度,默认为0arc:总弧度,默认为Math.PI*2ht.Default.createRoundRectModel(top, bottom)构建圆角矩形体模型
top:是否有顶部bottom:是否有底部ht.Default.createStarModel(top, bottom)构建星形体模型
top:是否有顶部bottom:是否有底部ht.Default.createRectModel(top, bottom)构建矩形体模型
top:是否有顶部bottom:是否有底部ht.Default.createTriangleModel(top, bottom)构建三角形体模型
top:是否有顶部bottom:是否有底部ht.Default.createRightTriangleModel(top, bottom)构建直角三角形体模型
top:是否有顶部bottom:是否有底部ht.Default.createParallelogramModel(top, bottom)构建平行四边形体模型
top:是否有顶部bottom:是否有底部ht.Default.createTrapezoidModel(top, bottom)构建梯形体模型
top:是否有顶部bottom:是否有底部ht.Default.createExtrusionModel(array, segments, top, bottom, resolution, repeatUVLength, tall, elevation)根据xz平面多边形,挤压形成3D模型。
array:定义xz平面的所有点坐标,格式为:[x1, z1, x2, z2, ...]segments:定义点连接样式,数组元素为整型值,为空则代表所有点连成直线moveTo,占用1个点信息lineTo,占用1个点信息quadraticCurveTo,占用2个点信息bezierCurveTo,占用3个点信息closePath,不占用点信息top:是否有顶部bottom:是否有底部resolution:微分段数repeatUVLength:默认为空,设置值后顶部和底部的贴图将根据制定长度值进行重复tall:模型高度,默认为0.5elevation:模型中心的y轴位置,默认值为0ht.Default.createRingModel(array, segments, resolution, top, bottom, side, sideFrom, sideTo, from, to)根据xy平面的曲线,环绕一周形成3D模型。
array:定义xy平面的所有点坐标,格式为:[x1, y1, x2, y2, ...]segments:定义点连接样式,数组元素为整型值,为空则代表所有点连成直线moveTo,占用1个点信息lineTo,占用1个点信息quadraticCurveTo,占用2个点信息bezierCurveTo,占用3个点信息closePath,不占用点信息resolution:曲线微分段数top:是否有顶部bottom:是否有底部side:总边数sideFrom:起始边索引sideTo:结束边索引from:是否有起始面to:是否有结束面ht.Default.createSmoothRingModel(array, segments, vResolution, start, arc, hResolution)根据xy平面的曲线,环绕一周形成光滑3D模型。
array:定义xy平面的所有点坐标,格式为:[x1, y1, x2, y2, ...]segments:定义点连接样式,数组元素为整型值,为空则代表所有点连成直线moveTo,占用1个点信息lineTo,占用1个点信息quadraticCurveTo,占用2个点信息bezierCurveTo,占用3个点信息closePath,不占用点信息vResolution:曲线微分段数start:起始角度,默认为0arc:总弧度,默认为Math.PI*2hResolution:水平环绕微分段数ht.Default.createFrameModel(dx, dy, dz, params)构建框架体模型
dx:x轴框厚度,默认值为0.07dy:y轴框厚度,默认值为0.07dz:z轴框厚度,默认值为0.07params为JSON结构对象参数,对象属性为:top:true代表整体覆盖面,false代表该面为空,其余属性代表镂空,也即默认效果bottom:true代表整体覆盖面,false代表该面为空,其余属性代表镂空,也即默认效果left:true代表整体覆盖面,false代表该面为空,其余属性代表镂空,也即默认效果right:true代表整体覆盖面,false代表该面为空,其余属性代表镂空,也即默认效果front:true代表整体覆盖面,false代表该面为空,其余属性代表镂空,也即默认效果back:true代表整体覆盖面,false代表该面为空,其余属性代表镂空,也即默认效果除了模型基础章节介绍的构建模型顶点相关的基础属性外,模型JSON对象还可定义以下属性:
s3:数组类型如[0.5, 2.0, 3.0],代表模型x轴方向缩小一半,模型y轴方向扩大一倍,模型z轴方向扩大三倍t3:数组类型如[10, -20, 30],代表模型x轴方向平移10,模型y轴方向平移-20,模型z轴方向平移30r3:数组类型如[Math.PI/2, 0, 0],代表模型以x轴方向旋转Math.PI/2弧度,y和z轴方向不变rotationMode:旋转模型,控制r3的三个轴线旋转先后顺序,默认为xzy以下属性值默认取至style的相应shape3d.*,如果模型上进行设置,则模型上的定义具有更高优先级:
color:默认值为#3498DB,3d图形整体颜色topColor:默认值为undefined,3d图形顶面颜色bottomColCor:默认值为undefined,3d图形底面颜色fromColor:默认值为undefined,3d图形起始面颜色toColor:默认值为undefined,3d图形结束面颜色image:默认值为undefined,3d图形整体贴图topImage:默认值为undefined,3d图形顶面贴图bottomImage:默认值为undefined,3d图形底面贴图fromImage:默认值为undefined,3d图形起始面贴图toImage:默认值为undefined,3d图形结束面贴图light:默认值为true,3d图形是否受光线影响side:默认值为0,决定3d图形显示为几边型,为0时显示为平滑的曲面效果sideFrom:默认值为undefined,决定3d图形起始边位置sideTo:默认值为undefined,决定3d图形结束边位置visible:默认值为true,决定3d图形是否可见,该参数不影响label,note和icons等其他部分元素fromVisible:默认值为true,决定3d图形起始面是否可见toVisible:默认值为true,决定3d图形结束面是否可见topVisible:默认值为true,决定3d图形顶面是否可见bottomVisible:默认值为true,决定3d图形底面是否可见torusRadius:默认值为0.17,决定3d圆环形管半径resolution:默认值为24,决定3d图形分段数,和side类似但决定不同的方向的分段,数值越大越均匀但影响性能opacity:默认值为undefined,决定3d图形的透明度,值范围0~1reverseFlip:默认值为false,决定3d图形的反面是否显示正面的内容reverseColor:#868686,决定3d图形的反面颜色reverseCull:默认值为false,决定3d图形的反面是否显示,隐藏背面可提高性能transparent:默认值为false,决定3d图形是否透明uvOffset:默认值为undefined,决定3d图形整体贴图的uv偏移,格式为[0.5, 0.5]uvScale:默认值为undefined,决定3d图形整体贴图的uv缩放,格式为[3, 2]topUvOffset:默认值为undefined,决定3d图形顶面贴图的uv偏移,格式为[0.5, 0.5]topUvScale:默认值为undefined,决定3d图形顶面贴图的uv缩放,格式为[3, 2]bottomUvOffset:默认值为undefined,决定3d图形底面贴图的uv偏移,格式为[0.5, 0.5]bottomUvScale:默认值为undefined,决定3d图形底面贴图的uv缩放,格式为[3, 2]fromUvOffset:默认值为undefined,决定3d图形起始面贴图的uv偏移,格式为[0.5, 0.5]fromUvScale:默认值为undefined,决定3d图形起始面贴图的uv缩放,格式为[3, 2]toUvOffset:默认值为undefined,决定3d图形结束面贴图的uv偏移,格式为[0.5, 0.5]toUvScale:默认值为undefined,决定3d图形结束面贴图的uv缩放,格式为[3, 2]较为复杂的模型往往需要多个小模型组合而成,采用目前掌握的知识可通过多个Node图元分别设置不同部位模型的shape3d属性实现,
如果需要多个部分粘在一起的效果,可通过将这些Node图元相互通过Node#setHost函数相互环状吸附在一起。
但这样的解决方案会导致对象管理的不方便,例如一把椅子可有由四条腿和一个平面组成,但从对象管理角度或用户使用角度,
更希望整个椅子就是一个Node对象,在TreeView视图上仅为一个节点,这种情况就是使用模型组合功能的最佳场合了。
组合模型的定义非常简单且灵活,以Array数组方式即可组合多个模型
ht.Default.setShape3dModel('A', modelA);
ht.Default.setShape3dModel('B', modelB);
ht.Default.setShape3dModel('C', ['A', 'B']);
以上代码分别定义了A、B和C三种模型,其中模型C为A和B两种模型的组合。
ht.Default.setShape3dModel('E', ['A', 'B', 'sphere', modelD])
组合模型的数组元素不仅可为新定义的模型名称,还可为预定义的模型名称,以及直接为模型JSON对象,
以上代码定义了新模型E,该模型由自定义的A和B模型,预定义的sphere球体,以及modelD四个模型组合而成。
ht.Default.setShape3dModel('F', [
{
shape3d: 'box',
color: 'yellow'
},
{
shape3d: 'box',
s3: [0.5, 0.5, 1.1],
color: 'red'
}
]);
模型属性章节的属性不仅可设置在模型的JSON对象上,也可以直接在组合模型数组中的新元素对象上设置,
以上代码定义了新模型F,其由两个box模型组合而成,模型类型由shape3d的元素属性定义,还可设置color和s3等模型参数。
ht.Default.setShape3dModel('G', [
{
shape3d: ['cylinder', {shape3d: 'cone', color: 'green', t3: [1, 0, 0]}],
color: 'yellow',
t3: [-0.5, 0, -1]
},
{
shape3d: 'box',
s3: [0.3, 0.3, 0.3],
color: 'red'
}
]);
组合数组元素对象的shape3d属性值,依然可为数组类型,以实现无限递归的组合层次嵌套,以上代码定义的G模型呈现效果如下图:
详见数据绑定手册
HT提供了众多基础图元类型,但为快速构建房间楼宇即各种场景装饰物,在建模扩展包种增加了更多的图元类型,方便用户用API或可视化编辑工具快速搭建项目场景。
ht.Symbol继承于ht.Node,常用于展示花盆、公告牌等装饰物的平面图片,其默认设置了all.visible为false,重载了setIcon函数,
在设置icon的同时通过addStyleIcon将图片也用于显示在Graph3dView上。使用Symbol一般只需要再构造函数或通过setIcon传入参数,
然后设置p3位置即可。
ht.Symbol(icon, autorotate, transaprent)setIcon(icon, autorotate, transaprent)icon 指定显示的图片autorotate 默认值为false,控制是否自动朝向眼睛的方向,可设为true或x、y、z,其中y代表限定沿着y轴转动transaprent 代表是否要显示为透明,默认为falsesetIcon函数会返回注册的json对象,可用于再设置额外的参数,可参见3D手册图标章节
CSG是 Constructive Solid Geometry 建模技术的简称,
通过裁剪subtract、融合union和相交intersect的运算,组合出复杂模型效果,HT封装了ht.CSGNode和ht.CSGShape等
图元类型来支持CSG的组合功能,常用于墙面的门窗挖空凿洞的应用场景。
ht.CSGNode继承于ht.Node,当style的shape3d属性为空时显示为六面体效果,CSGNode如果通过setHost吸附到
宿主CSGNode或CSGShape后,宿主CSGNode或CSGShape可与吸附的CSGNode图元进行CSG的组合建模。
attach.cull:默认值为false,该值决定是否对相交的部分进行剔除attach.operation:默认值为subtract,可取以下值:subtract:代表对host的CSGNode或CSGShape图元进行挖空裁剪union:代表对host的CSGNode或CSGShape图元进行融合intersect:代表对host的CSGNode或CSGShape图元取相交部分host图元不进行任何操作当宿主CSGNode或CSGShape进行组合生成新的模型部分的渲染由csg.*的参数来控制,与all.*等六面体的其他面的控制方式一致,
参见3D手册的六面体章节。
csg.light:是否受光线影响,受光线影响时正面看时最亮,侧面看时变暗csg.visible:是否可见,csg.color:颜色csg.image:贴图,优先级高于csg.colorcsg.blend:染色颜色,优先级高于csg.color,如果有贴图时,则对贴图染色csg.opacity:透明度,值范围0~1csg.reverse.flip:反面是否显示正面的内容csg.reverse.color:反面颜色,即立方体内部面颜色csg.reverse.cull:反面是否可见,即立方体内部面是否显示,一般六面闭合立方体,可不显示以提高性能csg.transparent:是否透明,若color|image|opacity属性出现透明区域情况下,一般需设置为truecsg.discard.selectable: 代表贴图透明度低到被剔除的部分也能点击选中,可设置为false则被剔除部分不可选中csg.cull.color: 设置被裁切位置显示的颜色值csg.cull.box: 设置是否用模型的包围盒进行裁切,默认为true,表示采用Node包围盒裁切,可设置为false,表示采用Node设置的Shape3dModel进行裁切。注意,如果Shape3dModel存在凹陷的面,不建议将该属性设置为false需要注意的是并没有csg.uv,csg.uv.scale和csg.uv.offset等贴图相关参数,csg相关表面的uv值由吸附者的六面贴图相关参数决定,
只有贴图图片参数由host的csg.image参数决定。
可以把
CSG.*理解为除left/rigth/top/bottom/front/back外的第七个面
ht.CSGBox继承于ht.CSGNode,其除具备父类CSGNode的挖空等功能外,还可对六个面进行旋转展开关闭的操作,
因此增加了以下面相关style属性,由于六个面的参数一致,以下仅以front进行说明:
front.toggleable:是否允许双击面进行展开和关闭的操作,默认为falsefront.expanded:当前是否处于展开状态,默认为falsefront.angle:当前状态旋转角度,默认为0front.start:关闭状态的起始旋转弧度,默认为0front.end:展开状态的结束旋转弧度,默认为Math.PI/2front.axis:展开和关闭操作的旋转轴,可取以下值,默认为leftleft:以左边为轴进行旋转right:以右边为轴进行旋转top:以顶边为轴进行旋转bottom:以底边为轴进行旋转v:以中间垂直线为轴进行旋转h:以中间水平线为轴进行旋转以上的front.expanded和front.angle这两个参数一般无需用户直接操作,ht.CSGBox提供了以下函数封装,
参见表单手册 Unboxing 例子
toggleFace(face, anim):切换面当前展开或关闭状态,face可取值left|right|top|bottom|front|back,anim代表是否动画isFaceExpanded(face):判断面当前是否处于展开状态,face可取值left|right|top|bottom|front|backsetFaceExpanded(face, expanded, anim):设置面展开或合并状态,expanded可取值true|false,anim代表是否动画注意以上面相关参数并无
all.*的对应六面统一参数,CSGBox的相关面参数只能每个面独立设置
ht.DoorWindow继承于ht.CSGNode,其除具备父类CSGNode的挖空等功能外,还可进行整体的旋转展开关闭的操作,
常用于作为门或窗的业务对象,吸附于CSGNode或CSGShape的host作为墙面的图元,
DoorWindow增加了以下style参数进行控制,其中dw为DoorWindow的简称:
dw.flip:对图元显示进行翻转,相当于沿z轴旋转180度dw.s3:对图元显示尺寸在原有基础上再进行缩放,默认值[0.999, 0.999, 0.5]代表x和y收缩了0.001,z收缩了0.5dw.t3:对图元显示位置在原有基础上再进行绝对位置偏移,默认值为空代表不偏移dw.toggleable:是否允许双击进行展开和关闭的操作,默认为truedw.expanded:当前图元是否处于展开状态,默认为falsedw.angle:当前状态旋转角度,默认为0dw.start:关闭状态的起始旋转弧度,默认为0dw.end:展开状态的结束旋转弧度,默认为Math.PI/2dw.axis:展开和关闭操作的旋转轴,可取以下值,默认为leftleft:以左边为轴进行旋转right:以右边为轴进行旋转top:以顶边为轴进行旋转bottom:以底边为轴进行旋转v:以中间垂直线为轴进行旋转h:以中间水平线为轴进行旋转ht.CSGShape继承于ht.Shape,目前仅支持忽略segments参数的折线墙面效果,CSGNode如果通过setHost吸附到宿主CSGShape后,
CSGShape可与吸附的CSGNode图元进行CSG的组合建模。
attach.index:默认值为-1,用于CSGNode吸附到Shape图元时使用,代表所在Shape的线段索引attach.offset:默认值为0,与attach.index参数结合使用,代表吸附在CSGShape图元所在线段的偏移位置attach.offset.relative:默认值为false,如果为true则偏移量代表所在线段长度乘以attach.offset值attach.offset.opposite:默认值为false,与attach.offset参数结合使用,代表所在线段的正方向还是反方向偏移attach.thickness:Node默认值为空,CSGNode默认值为1.001,CSGNode的height属性值由Shape的thickness乘以该值决定attach.gap:默认值为0,代表与线段垂直方向的偏移attach.gap.relative:默认值为false,如果为true则与线段垂直方向的偏移为所Shape的thickness值乘以attach.gap当吸附者CSGNode设置了以上style参数后,则其会自动调节自身大小、位置和旋转角度,使其保持定位在Shape对应的线段上,
该功能不仅适用于ht.CSGShape,也适用于ht.Shape的父类图元。
CSGShape类型对ht.Shape进行了简化,除不支持segments参数外,还无效了setRotation、setRotationX和setRotationZ旋转功能。