我正在测试ARKit实现,我的一部分实验只是导入动画模型,让它像Apple场景示例中包含的其他静态模型一样遵循AR Scene的运动。
我从Apple的SceneKit示例中抓取了一个动画3D模型 https://developer.apple.com/library/content/samplecode/SceneKitAnimations/Introduction/Intro.html 并将其放入简单的ARKit测试项目中。 https://viewar.com/apple-augmented-reality-arkit-for-ios/
结果是:它显示模型,并且也是动画,但模型保持“跟随”我而不是停留在AR空间中的相同位置。 奇怪的是,它不仅仅是坚持在屏幕上的相同位置,而是在AR空间中一直漂浮在我的头顶上。
我对3D事物太新了,无法弄清楚发生了什么。 你们有什么想法吗?
代码是这样的。
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
var _animations = [CAAnimation]()
var charNode : SCNNode!
override func viewDidLoad() {
super.viewDidLoad()
// Set the view's delegate
sceneView.delegate = self
// Show statistics such as fps and timing information
sceneView.showsStatistics = true
// Create a new scene (Keep this ship just as a reference)
let scene = SCNScene(named: "art.scnassets/ship.scn")!
// Set the scene to the view
sceneView.scene = scene
// Load the DAE file and the associated animations
loadSceneAndAnimations();
// Be idle by default
playAnimation(ASCAnimation.Walk);
}
// MARK: Playing animations
func playAnimation(_ animation: ASCAnimation) {
// Use the same animation key for all the animations except "idle".
// When we will add an animation it will replace the animation currently
// playing (if any) but the idle animation will remain active for ever.
let key:String = animation == .Idle ? "idleAnimation" : "otherAnimation";
// Add the animation - it will start playing right away
sceneView.scene.rootNode.addAnimation(_animations[animation.rawValue], forKey: key);
}
// MARK: Animation loading
func loadSceneAndAnimations () {
// Load the character from one of our dae documents, for instance "idle.dae"
let idleURL = Bundle.main.url(forResource: "art.scnassets/idle", withExtension: "dae");
let idleScene = try! SCNScene(url: idleURL!, options: nil);
// Merge the loaded scene into our main scene in order to
// place the character in our own scene
for child in idleScene.rootNode.childNodes {
sceneView.scene.rootNode.addChildNode(child)
}
// Load all the animations from their respective dae document
// The animation identifier can be found in the Node Properties inspector of the Scene Kit editor integrated into Xcode
loadAnimation(animation: .Attack, sceneName: "art.scnassets/attack", animationIdentifier: "attackID");
loadAnimation(animation: .Die, sceneName: "art.scnassets/die", animationIdentifier: "DeathID");
loadAnimation(animation: .Idle, sceneName: "art.scnassets/idle", animationIdentifier: "idleAnimationID");
loadAnimation(animation: .Run, sceneName: "art.scnassets/run", animationIdentifier: "RunID");
loadAnimation(animation: .Walk, sceneName: "art.scnassets/walk", animationIdentifier: "WalkID");
}
func loadAnimation(animation:ASCAnimation, sceneName:String, animationIdentifier:String) {
let sceneURL = Bundle.main.url(forResource: sceneName, withExtension: "dae");
let sceneSource = SCNSceneSource(url: sceneURL!, options: nil);
let animationObject = sceneSource?.entryWithIdentifier(animationIdentifier, withClass: CAAnimation.self)
// Store the animation for later use
_animations.append(animationObject!);
// Whether or not the animation should loop
if animation == .Idle || animation == .Run || animation == .Walk {
animationObject?.repeatCount = MAXFLOAT;
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a session configuration
let configuration = ARWorldTrackingSessionConfiguration()
// Run the view's session
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Pause the view's session
sceneView.session.pause()
}
func session(_ session: ARSession, didFailWithError error: Error) {
// Present an error message to the user
}
func sessionWasInterrupted(_ session: ARSession) {
// Inform the user that the session has been interrupted, for example, by presenting an overlay
}
func sessionInterruptionEnded(_ session: ARSession) {
// Reset tracking and/or remove existing anchors if consistent tracking is required
}
}
答案 0 :(得分:1)
我自己解决了。 它太傻了,但这只是因为模型呈现出非常巨大的尺寸,就像一个数百米的巨人。因为它太大了我几米左右的运动根本没有影响。糟糕的是它也漂浮得很高,所以它在某种程度上看起来不错。通过给出大约1/100的比例变换,它变得正常。
答案 1 :(得分:0)
看看ARSceneViewDelegate
,有方法
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor)
当ARKit检测到曲面时,它会将一个节点添加到您可以放置3D模型的场景中。您还需要适当地设置会话:
let configuration = ARWorldTrackingSessionConfiguration()
configuration.planeDetection = .horizontal
有关更多信息,请查看Apple提供的ARKit示例代码: https://github.com/gao0122/ARKit-Example-by-Apple/tree/master/ARKitExample