J.Doe!
Najpierw jest niewielka sztuczka. Jeśli chcesz użyć iPhone'a jako domyślnej pozycji, musisz zauważyć, że oś używana w scenieKit różni się od osi używanej przez DeviceMotion. Sprawdź oś:
sceneKit axis http://developer.apple.com/library/ios/documentation/SceneKit/Reference/SceneKit_Framework/Art/3d_coordinate_system_2x.png
Pierwszą rzeczą, którą trzeba ustawić jest położenie kamery. Po uruchomieniu projektu SceneKit tworzy on swoją kamerę w pozycji (0, 0, 15). Wystąpił problem z tym:
Wartości EulerAngles = (0,0,0) oznaczałyby, że obiekt znajdowałby się w płaszczyźnie xz, ale tak długo, jak patrzysz na Z, po prostu widzisz go z bok. Aby było to równoważne z układaniem iPhone'a, musisz ustawić kamerę tak, aby wyglądała z góry. Więc byłoby jakbyś patrząc na niego z telefonu (takich jak kamera, idk)
// create and add a camera to the scene
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
scene.rootNode.addChildNode(cameraNode)
// place the camera
cameraNode.position = SCNVector3(x: 0, y: 15, z: 0)
// but then you need to make the cameraNode face the ship (the origin of the axis), rotating it
cameraNode.eulerAngles.x = -Float(M_PI)*0.5 //or Float(M_PI)*1.5
Dzięki temu mamy zamiar zobaczyć statek z góry, więc pierwsza część jest wykonywana. Teraz musimy sprawić, aby statek pozostał "nieruchomy" (twarzą do ziemi) przy obrocie urządzenia.
//First we need to use SCNRendererDelegate
class GameViewController : UIViewController SCNSceneRendererDelegate{
private let motion = CMMotionManager();
...
Następnie na viewDidLoad:
//important if you remove the sceneKit initial action from the ship.
//The scene would be static, and static scenes do not trigger the renderer update, setting the playing property to true forces that:
scnView.playing = true;
if(motion.deviceMotionAvailable){
motion.startDeviceMotionUpdates();
motion.deviceMotionUpdateInterval = 1.0/60.0;
}
Potem idziemy do sposobu aktualizacji
Spójrz na osi: osi Y i Z są „włączane” Jeśli porównać oś sceneKit i oś deviceMotion. Z jest podniesiony do góry, a jednocześnie znajduje się z boku sceny, a Y jest na scenie, a jednocześnie z boku telefonu. Tak więc pitch, roll i yaw, odpowiednio związane z osiami X, Y i Z, będą stosowane jako pitch, yaw and roll.
Uwaga Złożyłem wartość przechyłu pozytywną, ponieważ jest coś innego "przełączonego". Trudno to sobie wyobrazić. Zobacz oś Y ruchu urządzenia jest skorelowana z osią Z sceny.Teraz wyobraźmy sobie obrót obiektu wzdłuż tej osi, w tym samym kierunku (na przykład w kierunku zgodnym z ruchem wskazówek zegara), zmierzałyby one w przeciwnych kierunkach z powodu rozmieszczenia osi. (możesz ustawić negatywny wynik rolki, aby zobaczyć, jak działa źle)
func renderer(renderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
if let rot = motion.deviceMotion?.attitude{
print("\(rot.pitch) \(rot.roll) \(rot.yaw)")
ship.eulerAngles.x = -Float(rot.pitch);
ship.eulerAngles.y = -Float(rot.yaw);
ship.eulerAngles.z = Float(rot.roll);
}
Nadzieję, że pomaga! Do zobaczenia!
To pytanie jest zbyt obszerne. – nhgrif
@nhgrif Zapisałem moje główne pytania powyżej. Niektóre z nich to więcej teorii niż aplikacji. Jednak moja definicja nie jest szeroka. Wyraźnie stwierdziłem, czego oczekiwałem i co poszło źle, kiedy to zrobiłem. –
Pytanie 1 samo w sobie nie jest zbyt szerokie, nie sądzę. Powinieneś rozważyć zawężenie zakresu tego posta do tego samego pytania, aby ten post nie był zamknięty z powodu wyjątkowo szerokiego zakresu. – nhgrif