推荐:将NSDT编辑器加入你的3D开发工具链介绍 网格对象是由三角形和顶点组成的形状 在CHAI3D中,多边形网格是定义多面体对象形状的顶点和三角形的集合。 顶点是一个位置以及其他信息,例如颜色、法线矢量和纹理坐标。由直线连接的两个顶点成为一条边。三个顶点通过三条边相互连接,定义一个三角形,这是欧几里得空间中最简单的多边形。 网格对象可以平移、旋转或调整大小,并具有分配给它们的材质和纹理属性。以下代码演示如何创建由4个顶点和2个三角形组成的带纹理的正方形。 usingnamespacechai3d; createamesh objectnewcMesh(); createatexturemap objectmtexturecTexture2d::create(); loadatexturefile objectmtextureloadFromFile(myTexture。jpg); enabletexturemapping object1setUseTexture(true); setmaterialtowhite object1mmaterialsetWhite(); createvertices intvertex0object0newVertex(); intvertex1object0newVertex(); intvertex2object0newVertex(); intvertex3object0newVertex(); setposition,surfacenormal,andtexturecoordinateforvertex0 object0mverticessetLocalPos(vertex0,0。1,0。1,0。0); object0mverticessetNormal(vertex0,0。0,0。0,1。0); object0mverticessetTexCoord(vertex0,0。0,0。0); setposition,surfacenormal,andtexturecoordinateforvertex1 object0mverticessetLocalPos(vertex1,0。1,0。1,0。0); object0mverticessetNormal(vertex1,0。0,0。0,1。0); object0mverticessetTexCoord(vertex1,1。0,0。0); setposition,surfacenormal,andtexturecoordinateforvertex2 object0mverticessetLocalPos(vertex2,0。1,0。1,0。0); object0mverticessetNormal(vertex2,0。0,0。0,1。0); object0mverticessetTexCoord(vertex2,1。0,1。0); setposition,surfacenormal,andtexturecoordinateforvertex3 object0mverticessetLocalPos(vertex3,0。1,0。1,0。0); object0mverticessetNormal(vertex3,0。0,0。0,1。0); object0mverticessetTexCoord(vertex3,0。0,1。0); createtwotrianglesbyassigningtheirvertexIDs object0mtrianglesnewTriangle(vertex0,vertex1,vertex2); object0mtrianglesnewTriangle(vertex0,vertex2,vertex3);渲染选项材质 材料属性定义表面如何反射光线。他们通过定义颜色值来实现这一点,其方式与灯光大致相同。材质具有漫射(直射)光、环境(散射)光和镜面反射(反射)光的颜色值,但这些值定义了光的分量如何从材质表面反射。更多信息可以在有关材料的部分找到。 材质属性可以启用或禁用,并且需要在世界中至少使用一个光源才能使对象可见。 usingnamespacechai3d; createamesh cMeshmeshnewcMesh(); addmeshtoworld worldaddChild(mesh); buildmeshusingacylinderprimitive cCreatePipe(mesh, 0。15, 0。05, 0。06, 32, 1, cVector3d(0。05,0。20,0。0), cMatrix3d(cDegToRad(0),cDegToRad(0),cDegToRad(170),CEULERORDERXYZ) ); enablematerialproperty cylindersetUseMaterial(true); (1)setmaterialbysimplyassigningacolorname meshmmaterialsetBlueCornflower(); (2)orsetmaterialbyassigningacolorvaluesforeachcomponent meshmmaterialmambient。set(0。2,0。1,0。1); meshmmaterialmdiffuse。set(0。6,0。3,0。3); meshmmaterialmspecular。set(1。0,1。0,1。0); meshmmaterialsetShininess(10);顶点颜色 可以为网格的每个顶点指定不同的颜色值。如果三角形的三个顶点共享不同的颜色,则三角形上任何点的颜色都是通过三种顶点颜色的插值来计算的。 三角形和顶点颜色 如果启用了材料属性,顶点颜色将与材料颜色组合在一起。通常将材质设置为白色并为不同的顶点分配颜色以产生所需的光晕。如果禁用材质属性,则忽略所有光源,并使用纯顶点颜色来渲染对象。 usingnamespacechai3d; createamesh cMeshmeshnewcMesh(); addmeshtoworld worldaddChild(mesh); createthreenewvertices intvertex0meshnewVertex(); intvertex1meshnewVertex(); intvertex2meshnewVertex(); setpositionofeachvertex meshmverticessetLocalPos(vertex0,0。0,0。0,0。0); meshmverticessetLocalPos(vertex1,0。0,1。0,0。0); meshmverticessetLocalPos(vertex2,1。0,1。0,0。0); assigncolorvaluetoeachvertex cColorfcolor(1。0,0。2,0。2); meshmverticessetColor(vertex0,color); meshmverticessetColor(vertex1,color); meshmverticessetColor(vertex2,color); createnewtrianglefromvertices meshnewTriangle(vertex0,vertex1,vertex2); enablevertexcolors meshsetUseVertexColors(true); computesurfacenormals meshcomputeAllNormals();纹理映射 纹理映射 纹理贴图将应用(映射)到形状或多边形的表面。此过程类似于将图案纸应用于纯白框。多边形中的每个顶点都通过显式分配或过程定义分配一个纹理坐标(在2d情况下也称为UV坐标)。然后,在多边形的表面插值图像采样位置,以生成视觉结果,该结果似乎比使用有限数量的多边形可以实现的更丰富。 要了解如何在CHAI3D中创建纹理,请参阅本页顶部的第一个示例。线框图 三角形可以在实心或线模式下渲染。 (左)固体模式。(右)线框模式。 usingnamespacechai3d; enablewireframerenderingmode meshsetWireMode(true); enablesolidrenderingmode meshsetWireMode(false);边缘 要同时渲染边和三角形,CHAI3D提供了显示三角形的选项,并覆盖根据相邻三角形之间所需的最小角度选择的边子集。 (左)实心和边缘。(右)仅边缘。 usingnamespacechai3d; computealledgesforwhichadjacenttriangleshavemorethan40degreesangle meshcomputeAllEdges(40); setlinewidthofedgesandcolor cColorfcolor; color。setBlack(); meshsetEdgeProperties(1,color); (1)enablesurfacesandedges meshsetShowTriangles(true); meshsetShowEdges(true); (2)enableedgesonly meshsetShowTriangles(false); meshsetShowEdges(true);面部剔除 背面剔除确定网格对象的三角形是否可见。这是图形管道中的一个步骤,用于测试三角形中的顶点在投影到屏幕上时是否按顺时针顺序显示。 usingnamespacechai3d; enableculling objectsetUseCulling(true); 如果启用了面部剔除,但投影在屏幕上的多边形具有逆时针缠绕,则它已旋转为背离相机,不会被绘制。 该过程通过减少程序绘制的多边形数量,使渲染对象更快、更高效。例如,在城市街道场景中,通常不需要在建筑物背对摄影机的侧面绘制多边形;它们被面向相机的侧面完全遮挡。 通常,如果背面剔除仅包含封闭和不透明的几何体,则可以假定在渲染场景中不会产生可见的伪影。在包含透明多边形的场景中,通过Alpha合成过程,后向多边形可能会变得可见。透明度、半透明性和混合 渲染相机的半透明镜头 透明的物理材质显示其后面的对象未被遮挡,并且不会从其表面反射光线。透明玻璃是一种近乎透明的材料。虽然玻璃允许大多数光线不受遮挡地通过,但实际上它也反射了一些光。完全透明的材料是完全看不见的。 半透明物理材质显示其后面的对象,但这些对象被半透明材质遮挡。此外,半透明材质会反射照射到它的一些光线,使材料可见。半透明材料的物理示例包括透明布料、薄塑料和烟熏玻璃。 透明和半透明通常是同义词。既不透明也不半透明的材料是不透明的。 混合是OpenGL的机制,用于将帧缓冲中已有的颜色与传入基元的颜色组合在一起。然后,这种组合的结果将存储回帧缓冲器中。混合经常用于模拟半透明的物理材质。一个例子是渲染汽车的烟熏玻璃挡风玻璃。驾驶员和内饰仍然可见,但它们被烟熏玻璃的深色所掩盖。表面法线 渲染网格的顶点法线 在CHAI3D中启用照明时,法线矢量用于确定在指定顶点或表面上接收的光量。如果尚未定义曲面法线,则可以通过取该三角形两条边的向量叉积来计算每个三角形的法线。出于调试目的,可以使用以下调用显示曲面法线: usingnamespacechai3d; computeallsurfacenormals meshcomputeAllNormals(); setnormalpropertiesfordisplay cColorfcolor; color。setOrangeTomato(); meshsetNormalsProperties(0。01,color); displaysurfacenormals meshsetShowNormals(true);多网格对象介绍 由于网格对象每个对象仅包含一个材质和纹理属性,因此创建使用材质和纹理集合的网格需要使用称为cMultiMesh的不同类,该类将网格列表连接在一起。通过在单独的网格对象中根据三角形的材质和纹理属性来组织三角形,可以有效地构建和渲染具有丰富属性集的复杂对象。 usingnamespacechai3d; createamultimeshobject cMultiMeshmultiMeshnewcMultiMesh(); addmultimeshobjecttoworld worldaddChild(multiMesh); createafirstmesh cMeshmesh1multiMeshnewMesh(); createasecondmesh cMeshmesh2multiMeshnewMesh();文件支持 CHAI3D支持3DS、OBJ和SLT文件格式来导入或导出模型。如果您希望导入不同格式的文件,可以使用Blender或VisualEnterpriseAuthor(以前称为DeepExploration)等应用程序来编辑文件并将其转换为所需的格式。 usingnamespacechai3d; load3DSmodelfile multiMeshloadFromFile(myModel。3ds); loadOBJmodelfile multiMeshloadFromFile(myModel。obj); loadSTLmodelfile multiMeshloadFromFile(myModel。stl); savemodelto3DSfile multiMeshsaveToFile(myModel。3ds); savemodeltoOBJfile multiMeshsaveToFile(myModel。obj); savemodeltoSTLfile multiMeshsaveToFile(myModel。stl);碰撞检测 碰撞检测器用于计算射线与组成网格(或多网格)的任何三角形之间的交点。为了使此操作快速进行,CHAI3D使用边界体积层次结构或BVH。BVH是一组几何对象上的树结构。所有几何对象都包裹在构成树的叶节点的边界体积中。然后将这些节点分组为小集合,并包含在较大的边界体积中。反过来,这些也以递归方式分组并封闭在其他较大的边界体积中,最终导致树结构在树的顶部具有单个边界体积。边界体积层次结构用于有效地支持对几何对象集的多项操作,例如在触觉交互计算、光线追踪或鼠标选择的碰撞检测中。 轴对齐边界体积层次结构 在CHAI3D中,必须在定义三角形后生成边界体积层次结构。如果修改了三角形或移动了顶点,则必须再次计算层次结构。更新碰撞树时,正确包含世界上使用的最大触觉点的半径非常重要。此信息用于创建足够大的包络,以检测与半径小于或等于定义阈值的接触点的任何交互。 usingnamespacechai3d; createaxisalignedboundingvolumehierarchy multiMeshcreateAABBCollisionDetector(toolRadius);触觉效果 网格对象的触觉渲染 为了触觉渲染网格对象,CHAI3D使用由Ruspini和Khatib开发的虚拟手指代理算法,类似于Zilles和Salisbury提出的上帝对象。虚拟代理是替代虚拟环境中物理手指或探测器的代表性对象。 Ruspini和Khatib的手指代理算法 上图说明了虚拟代理的运动,因为触觉设备的位置发生了变化。代理的运动试图始终朝着目标移动。当畅通无阻时,代理直接向目标移动。当代理遇到障碍物时,无法直接移动,但代理仍可以通过沿一个或多个约束曲面移动来缩短到目标的距离。选择运动以局部最小化到目标的距离。当代理无法减少其与目标的距离时,它将停止在本地最小配置处。力是通过对触觉设备和代理位置之间的虚拟弹簧进行建模来计算的。弹簧的刚度在材料属性中定义。 usingnamespacechai3d; createcollisiondetector meshcreateAABBCollisionDetector(toolRadius); sethapticproperties meshmmaterialsetStiffness(1000); meshmmaterialsetStaticFriction(0。3); meshmmaterialsetDynamicFriction(0。4); 还可以通过材料属性等级激活和调整其他触觉效果。触觉效果使用势场算法,任何通用形状对象也支持这些算法。请注意,网格对象目前不支持磁性效果。 usingnamespacechai3d; createahapticstickslipeffect meshcreateEffectStickSlip(); sethapticproperties meshmmaterialsetStickSlipForceMax(5。0); meshmmaterialsetStickSlipStiffness(1000); 3D建模学习工作室翻译整理,转载请标明出处!