2015-10-22 3 views
5

Итак, у меня есть немного проекта, который я пытаюсь сделать. Я пытаюсь получить вращение устройств относительно силы тяжести и перевод с того места, где он начался. Таким образом, в основном получение «отслеживания» данных для устройства. Я планирую в основном применить это, сделав 3d pt, который будет имитировать данные, которые я записываю с устройства позже.Пожалуйста, помогите мне правильно применить данные о вращении устройства

В любом случае, чтобы попытаться достичь этого, я подумал, что лучше всего работать с набором сюжетов, чтобы я мог видеть вещи в трех измерениях точно так же, как и данные, которые я пытаюсь записать. Прямо сейчас я пытаюсь заставить корабль вращаться так, чтобы он всегда выглядел следующим образом (например, его на земле или что-то еще), что бы не вращало устройство. Я полагаю, что когда я это сделаю, это будет сич, чтобы применить это к точке. Таким образом, я сделал следующий код:

if let attitude = motionManager.deviceMotion?.attitude { 
     print(attitude) 


     ship.eulerAngles.y = -Float(attitude.roll) 
     ship.eulerAngles.z = -Float(attitude.yaw) 
     ship.eulerAngles.x = -Float(attitude.pitch) 

    } 

Когда вы запускаете только одну из линий вращения, все прекрасно. Он правильно ведет себя на этой оси. Однако, когда я делаю все три оси, он становится хаотичным и выполняет далеко не ожидаемое с дрожанием и всем остальным.

Я думаю, мой вопрос: Кто-нибудь знает, как исправить мой код выше, чтобы корабль правильно стоял «вертикально», независимо от ориентации.

+0

Этот вопрос - путь, слишком широкий. – nhgrif

+1

@ nhgrif Я записал свои основные вопросы выше. Конечно, некоторые из них - более теория, чем приложение. Однако мой вопрос не является общим вопросом. Я четко заявил, на что я надеялся, и что случилось, когда я это сделал. –

+0

Вопрос 1 сам не слишком широк, я не думаю. Вы должны рассмотреть вопрос о сужении сферы действия этого поста вплоть до этого вопроса, чтобы этот пост не был закрыт для того, чтобы быть чрезвычайно широким. – nhgrif

ответ

8

J.Doe!

Сначала есть небольшой трюк. Если вы хотите использовать iphone в качестве позиции по умолчанию, вы должны заметить, что ось, используемая в sceneKit, отличается от используемой DeviceMotion. Проверьте ось:

deviceMotion axis sceneKit axis http://developer.apple.com/library/ios/documentation/SceneKit/Reference/SceneKit_Framework/Art/3d_coordinate_system_2x.png

Первое, что вам нужно установить это положение камеры. Когда вы запускаете проект SceneKit, он создает вашу камеру в позиции (0, 0, 15). Существует проблема с этим:

Значения eulerAngles = (0,0,0) означают, что объект будет находиться в плоскости xz, но пока вы смотрите на Z, вы просто видите это из боковая сторона. Для того чтобы это было эквивалентно укладке iphone, вам нужно будет установить камеру, чтобы смотреть сверху. Так было бы, как вы смотрели на него с телефона (например, камеры, ИДК)

// 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 

С этим мы будем видеть корабль сверху, так что первая часть выполнена. Теперь мы должны сделать корабль «неподвижным» (лицом к земле) с вращением устройства.

//First we need to use SCNRendererDelegate 
class GameViewController : UIViewController SCNSceneRendererDelegate{ 
    private let motion = CMMotionManager(); 
... 

Тогда на 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; 
} 

Тогда мы идем к методу обновления

Посмотрите на оси: ось Y и Z являются «коммутируемого» если сравнивать ось sceneKit и ось устройства. Z находится на телефоне, а находится сбоку на сцене, а Y - на сцене, а в стороне от телефона. Таким образом, шаг, рулон и рыскание, соответственно связанные с осью X, Y и Z, будут применяться как шаг, рыскание и рулон.

Уведомление Я положил значение рулона положительным, потому что есть что-то еще «переключенное». Это трудно представить. См. Ось Y движения устройства коррелирует с осью Z сцены.Теперь представьте себе вращение объекта вдоль этой оси в том же направлении (например, по часовой стрелке), они будут двигаться в противоположных направлениях из-за расположения оси. (вы можете установить отрицательный валик также посмотреть, как он пойдет не так)

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); 
    } 

Надеюсь, что это поможет! До встречи!

+0

Большое вам спасибо за такой тщательный ответ! –

Смежные вопросы