说明
本文讲述扇形平面的生成。
几何
扇形的排列与圆形高度一致。惟一不同的是,排列的起点不再是从圆心开始,而是从扇形的内径开始。同样道理,贴图也有两种模式:环绕模式,与平铺模式。
与上文讲的圆形类似,当角度分辨率不够时,圆形会呈现三角形或菱形或五边形,而扇形会呈现多边形凹槽状态。
代码
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])
}