S04E04:扇形平面网格生成

207 阅读1分钟

说明

本文讲述扇形平面的生成。

几何

扇形的排列与圆形高度一致。惟一不同的是,排列的起点不再是从圆心开始,而是从扇形的内径开始。同样道理,贴图也有两种模式:环绕模式,与平铺模式。

与上文讲的圆形类似,当角度分辨率不够时,圆形会呈现三角形或菱形或五边形,而扇形会呈现多边形凹槽状态。

代码

public static func generateArcPlane(innerRadius: Float, outerRadius: Float, startAngle: Float, endAngle: Float, angularResolution: Int, radialResolution: Int, circleUV: Bool = true) throws -> MeshResource {
    var descr = MeshDescriptor()
    var meshPositions: [SIMD3<Float>] = []
    var indices: [UInt32] = []
    var textureMap: [SIMD2<Float>] = []
    
    let radial = radialResolution > 0 ? radialResolution : 1
    let angular = angularResolution > 2 ? angularResolution : 3;

    let radialf = Float(radial)
    let angularf = Float(angular)
    
    let radialInc = (outerRadius - innerRadius) / radialf
    let angularInc = (endAngle - startAngle) / angularf

    let perArc = angular + 1
    
    for r in 0...radial {
        let rf = Float(r)
        let rad = innerRadius + rf * radialInc
        let rFactor = rad / outerRadius
        for a in 0...angular {
            let af = Float(a)
            let angle = startAngle + af * angularInc
            let ca = cos(angle)
            let sa = sin(angle)

            meshPositions.append(SIMD3<Float>(rad * ca, 0, rad * sa))
            if circleUV {
                textureMap.append(SIMD2<Float>(rFactor, 1 - af / angularf))
            } else {
                textureMap.append(SIMD2<Float>((ca*rFactor)/2+0.5, 0.5-(sa*rFactor)/2))
            }
            
            if (r != radial && a != angular) {
                let index = UInt32(a + r * perArc)

                let br = index
                let bl = br + 1
                let tr = br + UInt32(perArc)
                let tl = bl + UInt32(perArc)

                indices.append(contentsOf: [tr,br,bl,
                                            tl,tr,bl])
            }
        }
    }
    
    
    descr.primitives = .triangles(indices)
    descr.positions = MeshBuffer(meshPositions)
    descr.textureCoordinates = MeshBuffers.TextureCoordinates(textureMap)
    return try .generate(from: [descr])
}