这是在上一篇文章画扇形的基础上实现的,基本上仍是来源于Laya官方提供的画圆柱的Mesh代码实现。c++
圆环相较于扇形或者圆柱,是增长了内径,要切除掉一部分中间区域。最终的表现为上下部分的圆环,内部、外部的封边。在画扇形、圆柱的基础上,须要改一下上下圆环,而后增长一个内部的封边。ide
一开始以为画上下的圆环很简单,就是圆环半径,减去圆环内径,而后把剩下的区域画出来就行,可是代码该咋写呢。。。后来想一下,圆柱体外部封边也能够当作画了一个环,那是否是就能够直接基于那部分代码来修改呢?spa
// 画出上圆环 for (let bv = 0; bv <= slices; bv++) { curAngle = bv * sliceAngle posY = halfHeight vertices[vc++] = Math.cos(curAngle) * innerRadius vertices[vc + (slices + 1) * 8 - 1] = Math.cos(curAngle) * radius vertices[vc++] = posY vertices[vc + (slices + 1) * 8 - 1] = posY vertices[vc++] = Math.sin(curAngle) * innerRadius vertices[vc + (slices + 1) * 8 - 1] = Math.sin(curAngle) * radius vertices[vc++] = 0 vertices[vc + (slices + 1) * 8 - 1] = 0 vertices[vc++] = 1 vertices[vc + (slices + 1) * 8 - 1] = 1 vertices[vc++] = 0 vertices[vc + (slices + 1) * 8 - 1] = 0 vertices[vc++] = 1 - bv * 1 / slices vertices[vc + (slices + 1) * 8 - 1] = 1 - bv * 1 / slices vertices[vc++] = 0 vertices[vc + (slices + 1) * 8 - 1] = 1 } vc += (slices + 1) * 8 // 上环显示的是正面,因此顶点索引要顺序 for (let ri = 0; ri < slices; ri++) { indices[ic++] = ri + verticeCount + (slices + 1) indices[ic++] = ri + verticeCount + 1 indices[ic++] = ri + verticeCount indices[ic++] = ri + verticeCount + (slices + 1) indices[ic++] = ri + verticeCount + (slices + 1) + 1 indices[ic++] = ri + verticeCount + 1 } verticeCount += 2 * (slices + 1)
上述代码就是在画圆柱外部封边的基础上修改而来的,红色标记的就是修改的地方,把坐标改为内外径而已。code
内部封边,则基本上能够照着外封边的代码来改:blog
// 画出厚度内圈 for (let rv = 0; rv <= slices; rv++) { curAngle = rv * sliceAngle posX = Math.cos(curAngle) * innerRadius posY = halfHeight posZ = Math.sin(curAngle) * innerRadius vertices[vc++] = posX vertices[vc + (slices + 1) * 8 - 1] = posX vertices[vc++] = posY vertices[vc + (slices + 1) * 8 - 1] = -posY vertices[vc++] = posZ vertices[vc + (slices + 1) * 8 - 1] = posZ vertices[vc++] = posX vertices[vc + (slices + 1) * 8 - 1] = posX vertices[vc++] = 0 vertices[vc + (slices + 1) * 8 - 1] = 0 vertices[vc++] = posZ vertices[vc + (slices + 1) * 8 - 1] = posZ // 内圈显示的是背面,这里将数值调一下,显示背面 vertices[vc++] = rv * 1 / slices - 1 vertices[vc + (slices + 1) * 8 - 1] = rv * 1 / slices - 1 vertices[vc++] = 0 vertices[vc + (slices + 1) * 8 - 1] = 1 } vc += (slices + 1) * 8 // z轴三角 显示背面,逆序 for (let ri = 0; ri < slices; ri++) { indices[ic++] = ri + verticeCount + (slices + 1) indices[ic++] = ri + verticeCount indices[ic++] = ri + verticeCount + 1 indices[ic++] = ri + verticeCount + (slices + 1) indices[ic++] = ri + verticeCount + 1 indices[ic++] = ri + verticeCount + (slices + 1) + 1 } verticeCount += 2 * (slices + 1)
改动的地方基本上就是坐标值用的是内径的长度。而后有两个地方要注意,首先是索引顺序,由于内径在表现上来讲是看到了3D物体的背面,因此顶点索引是逆序的;再者是8个数据中倒数第二位UV坐标X值,这个是我猜着改的,改动以后,内部封边的贴图显示就正常了。索引
若是要画半环,那仍是跟画扇形同样,改一下顶点数,就能画出正常的3D环形了。class
自定义Mesh画出来的模型,也是能够添加物理碰撞器和刚体的,只是碰撞形状的数据,要用模型的数据,例如:基础
let ring = createRing(...) // 碰撞器 let ringCollider = ring.addComponent(Laya.PhysicsCollider) let ringShape = new Laya.MeshColliderShape() ringShape.mesh = ring.meshFilter.sharedMesh ringCollider.colliderShape = ringShape
以前在这个地方卡了好久,一直不生效,后来再改动改动坐标,发现是在3D世界中,物体相对位置不对,直接没有作到碰撞检测。数据