LayaAir2.0 自定义Mesh-画圆环

  这是在上一篇文章画扇形的基础上实现的,基本上仍是来源于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世界中,物体相对位置不对,直接没有作到碰撞检测。数据

相关文章
相关标签/搜索