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世界中,物體相對位置不對,直接沒有作到碰撞檢測。數據

相關文章
相關標籤/搜索