public void Calibration(CalibrationAxis axis, float angle) { if (ViveSR_DualCameraRig.Instance.TrackedCameraLeft == null || ViveSR_DualCameraRig.Instance.TrackedCameraRight == null) { return; } Vector3 vectorAxis = Vector3.zero; switch (axis) { case CalibrationAxis.X: vectorAxis = Vector3.right; break; case CalibrationAxis.Y: vectorAxis = Vector3.up; break; case CalibrationAxis.Z: vectorAxis = Vector3.forward; break; } if (CurrentCalibrationType == CalibrationType.RELATIVE) { ViveSR_DualCameraRig.Instance.TrackedCameraLeft.Anchor.transform.localEulerAngles += vectorAxis * angle; RelativeAngle += vectorAxis * angle; } if (CurrentCalibrationType == CalibrationType.ABSOLUTE) { ViveSR_DualCameraRig.Instance.TrackedCameraLeft.Anchor.transform.localEulerAngles += vectorAxis * angle; ViveSR_DualCameraRig.Instance.TrackedCameraRight.Anchor.transform.localEulerAngles += vectorAxis * angle; AbsoluteAngle += vectorAxis * angle; } }
/// <summary> /// Initialize the projective mapping from a line. /// length: Real world length of the line. /// a, b: Image coordinates of the line vertices. /// </summary> public void Initialize(float lengthWorld, PointF startImage, PointF endImage, CalibrationAxis calibrationAxis) { this.calibrationAxis = calibrationAxis; QuadrilateralF quadImage = MakeQuad(startImage, endImage, calibrationAxis); SizeF sizeWorld = new SizeF(lengthWorld, lengthWorld); Initialize(sizeWorld, quadImage); perspective = false; }
/// <summary> /// Build a quadrilateral from a single line. /// The quadrilateral will be a square with the original line at the bottom edge. /// </summary> private QuadrilateralF MakeQuad(PointF start, PointF end, CalibrationAxis calibrationAxis) { switch (calibrationAxis) { case CalibrationAxis.LineHorizontal: { // Rebuild a quadrilateral as a square, assuming the passed line is the bottom edge, left to right. // The base quadrilateral is defined as ABCD going CW from top-left, // the line is making up the DC vector which will map to the +X axis. PointF d = start; PointF c = end; PointF a = new PointF(d.X + (c.Y - d.Y), d.Y - (c.X - d.X)); PointF b = new PointF(a.X + (c.X - d.X), a.Y + (c.Y - d.Y)); return(new QuadrilateralF(a, b, c, d)); } case CalibrationAxis.LineVertical: { // Rebuild a quadrilateral as a square, assuming the passed line is the left edge, bottom to top. // The base quadrilateral is defined as ABCD going CW from top-left, // the line is making up the DA vector which will map to the +Y axis. PointF d = start; PointF a = end; PointF c = new PointF(d.X + (d.Y - a.Y), d.Y + (a.X - d.X)); PointF b = new PointF(a.X + (c.X - d.X), a.Y + (c.Y - d.Y)); return(new QuadrilateralF(a, b, c, d)); } case CalibrationAxis.ImageAxes: default: { // Rebuild a quadrilateral as a square aligned to the normal image axes (except Y goes up). // The base quadrilateral is defined as ABCD going CW from top-left, // the line length is giving the length of the DC edge of the square. float length = GeometryHelper.GetDistance(start, end); PointF d = start; PointF c = new PointF(d.X + length, d.Y); PointF a = new PointF(d.X + (c.Y - d.Y), d.Y - (c.X - d.X)); PointF b = new PointF(a.X + (c.X - d.X), a.Y + (c.Y - d.Y)); return(new QuadrilateralF(a, b, c, d)); } } }
public void ReadLineXml(XmlReader r, PointF scaling) { r.ReadStartElement(); float length = 0; SegmentF line = SegmentF.Empty; calibrationAxis = CalibrationAxis.LineHorizontal; while (r.NodeType == XmlNodeType.Element) { switch (r.Name) { case "Length": length = float.Parse(r.ReadElementContentAsString(), CultureInfo.InvariantCulture); break; case "Segment": line = ParseSegment(r, scaling); break; case "Origin": // Import from older format. origin = XmlHelper.ParsePointF(r.ReadElementContentAsString()); if (float.IsNaN(origin.X) || float.IsNaN(origin.Y)) { origin = PointF.Empty; } origin = origin.Scale(scaling.X, scaling.Y); break; case "Axis": calibrationAxis = (CalibrationAxis)Enum.Parse(typeof(CalibrationAxis), r.ReadElementContentAsString()); break; case "Scale": // Import and convert from older format. // Create a fake line of 100 px horizontal at the origin. float bakedScale = float.Parse(r.ReadElementContentAsString(), CultureInfo.InvariantCulture); float lengthPixels = 100; PointF start = origin; PointF end = origin.Translate(lengthPixels, 0); line = new SegmentF(start, end); length = lengthPixels * bakedScale; // The actual origin should be expressed in the calibrated plane coordinate system, which has its true origin at the A point of the quad. origin = new PointF(0, length); break; default: string unparsed = r.ReadOuterXml(); log.DebugFormat("Unparsed content in KVA XML: {0}", unparsed); break; } } r.ReadEndElement(); // Update mapping. size = new SizeF(length, length); quadImage = MakeQuad(line.Start, line.End, calibrationAxis); mapping.Update(new QuadrilateralF(size.Width, size.Height), quadImage); valid = quadImage.IsConvex; initialized = true; }
public void CalibrationByLine_Initialize(Guid id, float length, PointF a, PointF b, CalibrationAxis calibrationAxis) { calibrationDrawingId = id; PointF aRectif = distortionHelper.Undistort(a); PointF bRectif = distortionHelper.Undistort(b); calibrationPlane.Initialize(length, aRectif, bRectif, calibrationAxis); AfterCalibrationChanged(); }