public void ProcessData(MotionControllerModel mc) { if (_camera.Handle != IntPtr.Zero) { Vector3 rawPosition = Vector3.zero; Vector3 fusionPosition = Vector3.zero; PSMoveTrackerStatus trackerStatus = mc.TrackerStatus[_camera]; if (!mc.Design) { trackerStatus = PsMoveApi.psmove_tracker_get_status(_camera.Handle, mc.Handle); } if (trackerStatus == PSMoveTrackerStatus.Tracking) { float rx, ry, rrad; float fx, fy, fz; PsMoveApi.psmove_tracker_get_position(_camera.Handle, mc.Handle, out rx, out ry, out rrad); PsMoveApi.psmove_fusion_get_position(_camera.Fusion, mc.Handle, out fx, out fy, out fz); rx = (int)(rx + 0.5); ry = (int)(ry + 0.5); rawPosition = new Vector3(rx, ry, rrad); fusionPosition = new Vector3(fx, fy, fz); } else if (mc.Design) { switch (_camera.Calibration.Index) { case 0: rawPosition = new Vector3(129, 280, 8.970074f); break; case 1: rawPosition = new Vector3(180, 293, 11.9714022f); break; case 2: rawPosition = new Vector3(528, 286, 9.038924f); break; case 3: rawPosition = new Vector3(389, 275, 6.530668f); break; } } mc.TrackerStatus[_camera] = trackerStatus; mc.RawPosition[_camera] = rawPosition; mc.FusionPosition[_camera] = fusionPosition; if (trackerStatus == PSMoveTrackerStatus.Tracking || mc.Design) { // controller position -> rectangle in surrounding the sphere in image coordinates PointF[] imgPts = CvHelper.GetImagePointsF(mc.RawPosition[_camera]); ExtrinsicCameraParameters ex = CameraCalibration.FindExtrinsicCameraParams2( _camera.Calibration.ObjectPoints2D, imgPts, _camera.Calibration.IntrinsicParameters); Matrix <double> coordinatesInCameraSpace_homo = new Matrix <double>(new double[] { ex.TranslationVector[0, 0], ex.TranslationVector[1, 0], ex.TranslationVector[2, 0], 1 }); mc.CameraPosition[_camera] = new Vector3( (float)coordinatesInCameraSpace_homo[0, 0], (float)coordinatesInCameraSpace_homo[1, 0], (float)coordinatesInCameraSpace_homo[2, 0]); ex.RotationVector[0, 0] += (Math.PI / 180) * (_camera.Calibration.RotX + _camera.Calibration.XAngle); ex.RotationVector[1, 0] += (Math.PI / 180) * (_camera.Calibration.RotY + _camera.Calibration.YAngle); ex.RotationVector[2, 0] += (Math.PI / 180) * (_camera.Calibration.RotZ + _camera.Calibration.ZAngle); _camera.Calibration.ExtrinsicParameters[mc.Id] = ex; Matrix <double> minusRotation = new Matrix <double>(3, 3); minusRotation = CvHelper.Rotate( -_camera.Calibration.RotX - _camera.Calibration.XAngle, -_camera.Calibration.RotY - _camera.Calibration.YAngle, -_camera.Calibration.RotZ - _camera.Calibration.ZAngle); Matrix <double> R3x3_cameraToWorld = new Matrix <double>(3, 3); R3x3_cameraToWorld = CvHelper.Rotate( _camera.Calibration.RotX, _camera.Calibration.RotY + _camera.Calibration.YAngle, _camera.Calibration.RotZ); Matrix <double> rotInv = new Matrix <double>(3, 3); CvInvoke.cvInvert(ex.RotationVector.RotationMatrix.Ptr, rotInv, SOLVE_METHOD.CV_LU); Matrix <double> test = CvHelper.ConvertToHomogenous(-1 * R3x3_cameraToWorld); _camera.Calibration.ObjectPointsProjected = CameraCalibration.ProjectPoints( _camera.Calibration.ObjectPoints3D, _camera.Calibration.ExtrinsicParameters[mc.Id], _camera.Calibration.IntrinsicParameters); Matrix <double> cameraPositionInWorldSpace4x4 = new Matrix <double>(new double[, ] { { 1, 0, 0, _camera.Calibration.TranslationToWorld[0, 0] }, { 0, 1, 0, _camera.Calibration.TranslationToWorld[1, 0] }, { 0, 0, 1, _camera.Calibration.TranslationToWorld[2, 0] }, { 0, 0, 0, 1 }, }); Matrix <double> Rt_homo = CvHelper.ConvertToHomogenous(R3x3_cameraToWorld); Matrix <double> x_world_homo = CvHelper.ConvertToHomogenous(minusRotation) * coordinatesInCameraSpace_homo; Rt_homo[0, 3] = x_world_homo[0, 0]; Rt_homo[1, 3] = x_world_homo[1, 0]; Rt_homo[2, 3] = x_world_homo[2, 0]; x_world_homo = cameraPositionInWorldSpace4x4 * x_world_homo; Vector3 v3world = new Vector3((float)x_world_homo[0, 0], (float)x_world_homo[1, 0], (float)x_world_homo[2, 0]); mc.WorldPosition[_camera] = v3world; for (int i = mc.PositionHistory[_camera].Length - 1; i > 0; --i) { mc.PositionHistory[_camera][i] = mc.PositionHistory[_camera][i - 1]; } mc.PositionHistory[_camera][0] = v3world; } } } // ProcessData