context: using UnityEngine;
  using System.Collections;
  using System.Collections.Generic;
  using CSML;
  using Kinect = Windows.Kinect;
  using Ovr;
  
  public class RUISKinect2ToOculusDK2CalibrationProcess : RUISCalibrationProcess {
  	
  	public string getUpperText() {
  		return this.guiTextUpperLocal;
  	}
  	
  	public string getLowerText() {
  		return this.guiTextLowerLocal;
  	}
  	
  	// Abstract class variables
  	private RUISDevice inputDevice1, inputDevice2;
  	public string guiTextUpperLocal, guiTextLowerLocal;
  	public bool useScreen1, useScreen2;
  	
  	public override string guiTextUpper { get{return getUpperText();} }
  	public override string guiTextLower { get{return getLowerText();} }
  	
  	// Custom variables
  	private List<Vector3> samples_Kinect2, samples_OculusDK2;
  	private int numberOfSamplesTaken, numberOfSamplesToTake, numberOfSamplesPerSecond;
  	private float timeSinceLastSample, timeBetweenSamples, timeSinceScriptStart = 0;
  	public RUISCoordinateSystem coordinateSystem;
  	public RUISInputManager inputManager;
  	private bool oculusChecked = false, kinect2Checked = false, calibrationFinnished = false;
  	List<GameObject> calibrationSpheres;
  	private GameObject calibrationPhaseObjects, calibrationResultPhaseObjects, oculusDK2CameraObject, 
  	kinect2ModelObject, floorPlane, calibrationSphere, calibrationCube, depthView,
  	oculusDK2Icon, kinect2Icon, deviceModelObjects, depthViewObjects, iconObjects,
  	oculusRiftModel;
  	
  	private Vector3 lastPSMoveSample, lastKinect2Sample, lastOculusDK2Sample;
  	private string xmlFilename;
  	
  	private Matrix4x4 rotationMatrix, transformMatrix;
  	
  	Kinect2SourceManager kinect2SourceManager;
  	Kinect.Body[] bodyData; 
  	
  	private trackedBody[] trackingIDs = null; // Defined in RUISKinect2DepthView
  	private Dictionary<ulong, int> trackingIDtoIndex = new Dictionary<ulong, int>();
  //	private int kinectTrackingIndex;
  	private ulong kinectTrackingID;
  	
  	Quaternion kinect2PitchRotation = Quaternion.identity;
  	float kinect2DistanceFromFloor = 0;
  	Vector3 kinect2FloorNormal = Vector3.up;
  	RUISOVRManager ruisOvrManager;
  
  	bool device1Error, device2Error;
  	
  	public RUISKinect2ToOculusDK2CalibrationProcess(RUISCalibrationProcessSettings calibrationSettings) {
  		
  		this.inputDevice1 = RUISDevice.Oculus_DK2;
  		this.inputDevice2 = RUISDevice.Kinect_2;
  		
  		this.numberOfSamplesToTake = calibrationSettings.numberOfSamplesToTake;
  		this.numberOfSamplesPerSecond = calibrationSettings.numberOfSamplesPerSecond;
  		
  		trackingIDs = new trackedBody[6]; 
  		for(int y = 0; y < trackingIDs.Length; y++) {
  			trackingIDs[y] = new trackedBody(-1, false, 1);
  		}
  		
  		inputManager = MonoBehaviour.FindObjectOfType(typeof(RUISInputManager)) as RUISInputManager;
  		coordinateSystem = MonoBehaviour.FindObjectOfType(typeof(RUISCoordinateSystem)) as RUISCoordinateSystem;
  		kinect2SourceManager = MonoBehaviour.FindObjectOfType(typeof(Kinect2SourceManager)) as Kinect2SourceManager;
  		
  		this.timeSinceScriptStart = 0;
  		this.timeBetweenSamples = 1 / (float)numberOfSamplesPerSecond;
  		
  		// Limit sample rate
  		if(this.timeBetweenSamples < 0.1f) {
  			this.timeBetweenSamples = 0.1f;
  		}
  		
  		calibrationSpheres = new List<GameObject>();
  		
  		samples_Kinect2 = new List<Vector3>();
  		samples_OculusDK2 = new List<Vector3>();
  		
  		this.calibrationCube = calibrationSettings.calibrationCubePrefab;
  		this.calibrationSphere = calibrationSettings.calibrationSpherePrefab;
  		this.calibrationPhaseObjects = calibrationSettings.calibrationPhaseObjects;
  		this.calibrationResultPhaseObjects = calibrationSettings.calibrationResultPhaseObjects;
  		
  		this.deviceModelObjects = calibrationSettings.deviceModelObjects;
  		this.depthViewObjects = calibrationSettings.depthViewObjects;
  		this.iconObjects = calibrationSettings.iconObjects;
  		
  		if(GameObject.Find ("PSMoveWand") != null) GameObject.Find ("PSMoveWand").SetActive(false);
  		
  		// Models
  		this.oculusDK2CameraObject = GameObject.Find ("OculusDK2Camera");
  		this.kinect2ModelObject = GameObject.Find ("Kinect2Camera");
  		this.oculusRiftModel = GameObject.Find ("OculusRift");
  		
  		FixedFollowTransform followTransform = Component.FindObjectOfType<FixedFollowTransform>();
  		if(followTransform && this.oculusRiftModel)
  			followTransform.transformToFollow = this.oculusRiftModel.transform;
  		
  		// Depth view
  		this.depthView = GameObject.Find ("Kinect2DepthView");
  		
  		// Icons
  		this.oculusDK2Icon = GameObject.Find ("OculusDK2 Icon");
  		this.kinect2Icon = GameObject.Find ("Kinect2 Icon");
  		
  		this.floorPlane = GameObject.Find ("Floor");
  		
  		if(this.oculusDK2Icon && this.oculusDK2Icon.GetComponent<GUITexture>())
  			this.oculusDK2Icon.GetComponent<GUITexture>().pixelInset = new Rect(5.1f, 10.0f, 70.0f, 70.0f);
  		
  		foreach (Transform child in this.deviceModelObjects.transform)
  		{
  			child.gameObject.SetActive(false);
  		}
  		
  		foreach (Transform child in this.depthViewObjects.transform)
  		{
  			child.gameObject.SetActive(false);
  		}
  		
  		foreach (Transform child in this.iconObjects.transform)
  		{
  			child.gameObject.SetActive(false);
  		}
  		
  		if(this.oculusDK2CameraObject)
  			this.oculusDK2CameraObject.SetActive(true);
  		if(this.kinect2ModelObject)
  			this.kinect2ModelObject.SetActive(true);
  		if(this.oculusRiftModel)
  			this.oculusRiftModel.SetActive(true);
  		if(this.oculusDK2Icon)
  			this.oculusDK2Icon.SetActive(true);
  		if(this.kinect2Icon)
  			this.kinect2Icon.SetActive(true);
  		if(this.calibrationPhaseObjects)
  			this.calibrationPhaseObjects.SetActive(true);
  		if(this.calibrationResultPhaseObjects)
  			this.calibrationResultPhaseObjects.SetActive(false);
  		if(this.depthView)
  			this.depthView.SetActive(true);
  		this.xmlFilename = calibrationSettings.xmlFilename;
  	}
  	
  	
  	public override RUISCalibrationPhase InitialPhase(float deltaTime) {
  		
  		timeSinceScriptStart += deltaTime;
  		
  		if(timeSinceScriptStart < 3) {
  			this.guiTextLowerLocal = "Calibration of Kinect 2 and Oculus DK2\n\n Starting up...";
  			return RUISCalibrationPhase.Initial;
  		}
  		
  		if(timeSinceScriptStart < 4) {
  			this.guiTextLowerLocal = "Connecting to Oculus Rift DK2. \n\n Please wait...";
  			return RUISCalibrationPhase.Initial;
  		}
  		
  		if(!oculusChecked && timeSinceScriptStart > 4) {
  			oculusChecked = true;
  			
  			if ((RUISOVRManager.ovrHmd.GetTrackingState().StatusFlags & (uint)StatusBits.HmdConnected) == 0) { // Code from OVRManager.cs
  				this.guiTextLowerLocal = "Connecting to Oculus Rift DK2. \n\n Error: Could not connect to Oculus Rift DK2.";
  				return RUISCalibrationPhase.Invalid;
  			}
  		}	
  		
  		if(timeSinceScriptStart < 5) {
  			this.guiTextLowerLocal = "Connecting to Kinect 2. \n\n Please wait...";
  			return RUISCalibrationPhase.Initial;
  		}
  		
  		if(!kinect2Checked && timeSinceScriptStart > 5) {
  			kinect2Checked = true;	
  			if (!kinect2SourceManager.GetSensor().IsOpen || !kinect2SourceManager.GetSensor().IsAvailable) {
  				this.guiTextLowerLocal = "Connecting to Kinect 2. \n\n Error: Could not connect to Kinect 2.";
  				return RUISCalibrationPhase.Invalid;
  			}
  			else {
  				return RUISCalibrationPhase.Preparation;
  			}
  			
  		}	
  		
  		return RUISCalibrationPhase.Invalid; // Loop should not get this far
  	}
  	
  	
  	public override RUISCalibrationPhase PreparationPhase(float deltaTime) {
  		this.guiTextLowerLocal = "Step in front of the camera. \nHold Oculus Rift in your right hand.";
  		updateBodyData();
  		kinectTrackingID = 0;
  		
  		for(int a = 0; a < trackingIDs.Length; a++) {
  			if(trackingIDs[a].isTracking) {
  				kinectTrackingID = trackingIDs[a].trackingId;
  //				kinectTrackingIndex = trackingIDs[a].index;
  			}
  		}
  		
  		if(kinectTrackingID != 0) return RUISCalibrationPhase.ReadyToCalibrate;
  		else return RUISCalibrationPhase.Preparation;
  		
  	}
  	
  	
  	public override RUISCalibrationPhase ReadyToCalibratePhase(float deltaTime) {
  		return RUISCalibrationPhase.Calibration;
  	}
  	
  	
  	public override RUISCalibrationPhase CalibrationPhase(float deltaTime) {
  		
  		this.guiTextLowerLocal = string.Format(  "Calibrating... {0}/{1} samples taken.\n\n"
  		                                       + "Keep the Oculus Rift in your right hand\n"
  		                                       + "and make wide, calm motions with it.\n"
  		                                       + "Have both sensors see it.", numberOfSamplesTaken, numberOfSamplesToTake);
  		TakeSample(deltaTime);
  		
  		if(numberOfSamplesTaken >= numberOfSamplesToTake) 
  		{
  			timeSinceScriptStart = 0;
  			this.calibrationPhaseObjects.SetActive(false);
  			this.calibrationResultPhaseObjects.SetActive(true);
  			this.depthView.SetActive(false);
  			return RUISCalibrationPhase.ShowResults;
  		}
  		else 
  		{ 
  			return RUISCalibrationPhase.Calibration;
  		}
  	}
  	
  	
  	public override RUISCalibrationPhase ShowResultsPhase(float deltaTime) 
  	{
  		if(!calibrationFinnished) 
  		{
  			float totalErrorDistance, averageError;
  			CalculateTransformation();
  			
  			float distance = 0;
  			Vector3 error = Vector3.zero;
  			List<float> errorMagnitudes = new List<float>();
  			for (int i = 0; i < calibrationSpheres.Count; i++)
  			{
  
gt: 				GameObject sphere = calibrationSpheres[i];