package de.fau.cs.mad.fly.ios.input; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.utils.GdxRuntimeException; import com.badlogic.gdx.utils.TimeUtils; import de.fau.cs.mad.fly.profile.PlayerProfileManager; import de.fau.cs.mad.fly.settings.SettingManager; import org.robovm.apple.coremotion.CMAttitude; import org.robovm.apple.coremotion.CMDeviceMotion; import org.robovm.apple.coremotion.CMMotionManager; import de.fau.cs.mad.fly.game.FlightController; import de.fau.cs.mad.fly.player.Player; import de.fau.cs.mad.fly.profile.PlayerProfile; /** * Created by tschaei on 15.09.14. */ public class IOSFlightController extends FlightController{ private final CMMotionManager motionManager; private CMAttitude currentAttitude; public IOSFlightController(Player player, PlayerProfile playerProfile) { super(player, playerProfile); Gdx.app.log("IOSFlightController", "Instantiating motion manager"); motionManager = new CMMotionManager(); Gdx.app.log("IOSFlightController", motionManager.description()); motionManager.setDeviceMotionUpdateInterval(1.f / 60.f); motionManager.startDeviceMotionUpdates(); Gdx.app.log("IOSFlightController", "DeviceMotionUpdateInterval: " + motionManager.getDeviceMotionUpdateInterval()); Gdx.app.log("IOSFlightController", "DeviceMotionAvailable: " + motionManager.isDeviceMotionAvailable()); Gdx.app.log("IOSFlightController", "DeviceMotionActive: " + motionManager.isDeviceMotionActive()); } @Override public void resetSteering() { //necessary because it takes some time until the motionManager creates motion data. long startTime = TimeUtils.nanoTime(); do { if ( !motionManager.isDeviceMotionAvailable() || (TimeUtils.nanosToMillis(TimeUtils.timeSinceNanos(startTime)) / 1000.f) > 10.0f ) { Gdx.app.log("IOSFlightController.resetSteering", "CMMotionManager is not available. Falling back to touch."); PlayerProfileManager.getInstance().getCurrentPlayerProfile().getSettingManager().set(SettingManager.USE_TOUCH, true); useSensorData = false; return; } } while (motionManager.getDeviceMotion() == null); CMDeviceMotion motion = motionManager.getDeviceMotion(); Gdx.app.log("IOSFlightController.resetSteering", "motion object null: " + Boolean.toString(motion == null)); currentAttitude = motionManager.getDeviceMotion().getAttitude(); startRoll = (float) (currentAttitude.getRoll() * 180 / Math.PI); startPitch = -(float) (currentAttitude.getPitch() * 180 / Math.PI); } @Override protected void interpretSensorInput() { currentAttitude = motionManager.getDeviceMotion().getAttitude(); roll = (float) (currentAttitude.getRoll() * 180 / Math.PI); pitch = -(float) (currentAttitude.getPitch() * 180 / Math.PI); Gdx.app.log("IOSFlightController.interpretSensorInput", "Current roll: " + roll + "\nCurrent pitch: " + pitch + "\nStarting roll: " + startRoll + ". Starting pitch: " + startPitch); // removing oldest element in buffers if (rollInput.size() >= bufferSize) { rollInput.remove(0); pitchInput.remove(0); } // adding newest sensor-data to buffers rollInput.add(roll); pitchInput.add(pitch); roll = average(rollInput); pitch = average(pitchInput); // azimuth = computeAzimuth(roll, pitch, azimuth); float difRoll = roll - startRoll; if (Math.abs(difRoll) > 180) { difRoll -= Math.signum(difRoll) * 360; } float difPitch = pitch - startPitch; if (Math.abs(difPitch) > 180) { difPitch -= Math.signum(difPitch) * 360; } // capping the rotation to a maximum of 90 degrees if (Math.abs(difRoll) > maxRotate) { difRoll = maxRotate * Math.signum(difRoll); } if (Math.abs(difPitch) > maxRotate) { difPitch = maxRotate * Math.signum(difPitch); } rollFactor = 0.0f; azimuthFactor = 0.0f; // camera rotation according to smartphone rotation setAzimuthFactor(difPitch / maxRotate); setRollFactor(difRoll / -maxRotate); } }