我正在尝试编写以获取ARKit 3运动捕捉中的所有联合XYZ坐标,以获取XYZ来查找身体的所有角度。但我找不到XYZ坐标,因此无法进行下一步。
[我正在尝试使用character!.jointTransforms
来获取关节数据转换,也许是XYZ坐标,但是我试图跟踪一些运动,但是数字没有变化。
这是我的代码
import UIKit
import RealityKit
import ARKit
import Combine
class ViewController: UIViewController, ARSessionDelegate {
@IBOutlet var arView: ARView!
var character: BodyTrackedEntity?
let characterOffset: SIMD3<Float> = [0.0, 0, 0]
let characterAnchor = AnchorEntity()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
arView.session.delegate = self
guard ARBodyTrackingConfiguration.isSupported else {
fatalError("This feature is only supported on devices with an A12 chip")
}
let configuration = ARBodyTrackingConfiguration()
arView.session.run(configuration)
arView.scene.addAnchor(characterAnchor)
// Asynchronously load the 3D character.
var cancellable: AnyCancellable? = nil
cancellable = Entity.loadBodyTrackedAsync(named: "character/robot").sink(
receiveCompletion: { completion in
if case let .failure(error) = completion {
print("Error: Unable to load model: \(error.localizedDescription)")
}
cancellable?.cancel()
}, receiveValue: { (character: Entity) in
if let character = character as? BodyTrackedEntity {
// Scale the character to human size
character.scale = [1.0, 1.0, 1.0]
self.character = character
cancellable?.cancel()
} else {
print("Error: Unable to load model as BodyTrackedEntity")
}
})
}
func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
for anchor in anchors {
guard let bodyAnchor = anchor as? ARBodyAnchor else { continue }
let bodyPosition = simd_make_float3(bodyAnchor.transform.columns.3)
characterAnchor.position = bodyPosition + characterOffset
characterAnchor.orientation = Transform(matrix: bodyAnchor.transform).rotation
if let character = character, character.parent == nil {
characterAnchor.addChild(character)
}
let XYZArray = character!.jointTransforms.map({ (transform: RealityKit.Transform) -> SIMD3<Float> in
transform.translation
})
print(XYZArray)
}
}
}
该代码的引用者
https://developer.apple.com/documentation/arkit/capturing_body_motion_in_3d
检出此库PoseKit-https://github.com/d1l4y/PoseKit
import PoseKit
let poseKit = PoseKit()
func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
for anchor in anchors {
guard let bodyAnchor = anchor as? ARBodyAnchor else { continue }
print(poseKit.BodyTrackingPosition(bodyAnchor: bodyAnchor))
}
}
/// Gets the **hand's** position related to the **elbow** by comparing the angle between the forearm and the upper arm.
func ForearmToHandPos(bodyAnchor: ARBodyAnchor, forearmSubcase: ShoulderToForearmSubcase, HandTransform: simd_float4, ForearmTransform: simd_float4, ShoulderTransform: simd_float4, leftArm: Bool) -> ForearmToHandSubcase {
let handForearmVector = bodyPart.vector(joint1: ForearmTransform, joint2: HandTransform)
let shoulderForearmVector = bodyPart.vector(joint1: ForearmTransform, joint2: ShoulderTransform)
let forearmAngle = abs(bodyPart.angle(vector1: handForearmVector, vector2: shoulderForearmVector))
let crossVector = (simd_normalize(simd_cross(handForearmVector, shoulderForearmVector))) //produto vetorial deve bastar para saber o sentido
if simd_distance(ShoulderTransform, HandTransform) > 0.57 && forearmAngle > 125.0 {
return .straightHorizontal
}
if forearmSubcase == .verticalDownDiagonalBack || forearmSubcase == .verticalDownDiagonalFront || forearmSubcase == .verticalDownParallel || forearmSubcase == .horizontalTransverse {
return ForearmToHandDownCase(forearmAngle: forearmAngle, crossVector: crossVector, leftArm: leftArm)
} else if leftArm {
if crossVector.z < 0 {
if forearmAngle > 105.0 { return .bentDownOut }
else if forearmAngle > 80 { return .bentDown }
else if forearmAngle > 55 { return .bentDownIn }
} else {
if forearmAngle > 105.0 { return .bentUpOut }
else if forearmAngle > 80 { return .bentUp }
else if forearmAngle > 55 { return .bentUpIn }
}
} else {
if crossVector.z < 0 {
if forearmAngle > 105.0 { return .bentUpOut }
else if forearmAngle > 80 { return .bentUp }
else if forearmAngle > 55 { return .bentUpIn }
} else {
if forearmAngle > 105.0 { return .bentDownOut }
else if forearmAngle > 80 { return .bentDown }
else if forearmAngle > 55 { return .bentDownIn }
}
}
return .horizontalBentIn
}