fix(avlivebody): apply phase 2 review fixes
The phase 2 code review surfaced four follow-ups left after merge. The joint accessor indexed body.valid without checking its length, so a short valid array could crash on out-of-range access; it now guards i < body.valid.count. The viz mode name list was rebuilt on every modeName() call, so it is hoisted to a static constant. A Metal shader compile test is added to catch scene.metal regressions in CI. The dead SceneView placeholder, superseded by LayeredSceneView, is removed.
This commit is contained in:
@@ -22,7 +22,8 @@ enum SceneUniformBuilder {
|
||||
|
||||
if let body = skeletons.values.first {
|
||||
func j(_ i: Int) -> SIMD3<Float>? {
|
||||
(i < body.joints.count && body.valid[i]) ? body.joints[i] : nil
|
||||
(i < body.joints.count && i < body.valid.count
|
||||
&& body.valid[i]) ? body.joints[i] : nil
|
||||
}
|
||||
if let hips = j(hipsIdx) {
|
||||
u.body_x = hips.x; u.body_y = hips.y; u.body_z = hips.z
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import RealityKit
|
||||
import SwiftUI
|
||||
|
||||
/// SwiftUI bridge that hands the SceneController's ARView to the
|
||||
/// window and runs `setUp()` once.
|
||||
struct SceneView: NSViewRepresentable {
|
||||
let controller: SceneController
|
||||
|
||||
func makeNSView(context: Context) -> ARView {
|
||||
controller.setUp()
|
||||
return controller.arView
|
||||
}
|
||||
|
||||
func updateNSView(_ view: ARView, context: Context) {}
|
||||
}
|
||||
@@ -54,10 +54,10 @@ struct SettingsPanel: View {
|
||||
.background(.ultraThinMaterial)
|
||||
}
|
||||
|
||||
private static let modeNames = ["storm","tunnel","plasma","kaleido",
|
||||
"voronoi","metaballs","starfield","bars","hands3d","openpos"]
|
||||
static func modeName(_ i: Int) -> String {
|
||||
let n = ["storm","tunnel","plasma","kaleido","voronoi",
|
||||
"metaballs","starfield","bars","hands3d","openpos"]
|
||||
return n.indices.contains(i) ? "\(i) \(n[i])" : "\(i)"
|
||||
modeNames.indices.contains(i) ? "\(i) \(modeNames[i])" : "\(i)"
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// avlivebody-mac/Tests/AVLiveBodyTests/ShaderCompileTests.swift
|
||||
import XCTest
|
||||
import Metal
|
||||
@testable import AVLiveBody
|
||||
|
||||
final class ShaderCompileTests: XCTestCase {
|
||||
func testSceneMetalCompiles() throws {
|
||||
let here = URL(fileURLWithPath: #filePath) // .../Tests/AVLiveBodyTests/ShaderCompileTests.swift
|
||||
let shader = here
|
||||
.deletingLastPathComponent() // AVLiveBodyTests
|
||||
.deletingLastPathComponent() // Tests
|
||||
.deletingLastPathComponent() // avlivebody-mac
|
||||
.appendingPathComponent("Sources/AVLiveBody/Resources/scene.metal")
|
||||
let src = try String(contentsOf: shader, encoding: .utf8)
|
||||
guard let dev = MTLCreateSystemDefaultDevice() else {
|
||||
throw XCTSkip("no Metal device")
|
||||
}
|
||||
let lib = try dev.makeLibrary(source: src, options: MTLCompileOptions())
|
||||
XCTAssertNotNil(lib.makeFunction(name: "bg_vertex"))
|
||||
XCTAssertNotNil(lib.makeFunction(name: "bg_fragment"))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user