コード例 #1
0
        void CalculateBoundingRectangle(ILandmarkController landmark)
        {
            var polygonOutput = landmark.output as LandmarkOutputPolygon;

            if (polygonOutput != null)
            {
                if (m_LocalVerts.Count > 3)
                {
                    GeometryUtils.OrientedMinimumBoundingBox2D(m_LocalVerts, k_RectOutputVerts);
                    var rectCenter = Vector3.zero;
                    polygonOutput.localVertices.Clear();
                    for (int i = 0; i < k_RectOutputVerts.Length; i++)
                    {
                        rectCenter += k_RectOutputVerts[i];
                    }

                    rectCenter /= k_RectOutputVerts.Length;
                    for (int i = k_RectOutputVerts.Length - 1; i >= 0; i--)
                    {
                        // Add in reverse order because we want vertices in clockwise order to match plane vertex order
                        polygonOutput.localVertices.Add(k_RectOutputVerts[i] - rectCenter);
                    }

                    rectCenter = pose.ApplyOffsetTo(rectCenter);
                    polygonOutput.SetPolygonLocalSpace(polygonOutput.localVertices, new Pose(rectCenter, pose.rotation));
                }
            }
        }
コード例 #2
0
        public void SetupLandmark(ILandmarkController landmark)
        {
            // Use MARS session camera as the default target for "closest" landmark
            if (landmark.landmarkDefinition.GetEnumName <BasicPolygonLandmarks>() == BasicPolygonLandmarks.Closest)
            {
                var settings = landmark.settings as ClosestLandmarkSettings;
                if (settings != null)
                {
                    if (settings.target != null)
                    {
                        return;
                    }

                    var sessionCamera = MarsRuntimeUtils.GetSessionAssociatedCamera();
                    if (sessionCamera != null)
                    {
                        settings.target = sessionCamera.transform;
                    }
                }
                else
                {
                    Debug.LogError("Closest landmark is missing valid settings component", gameObject);
                }
            }
        }
コード例 #3
0
        void UpdateFaceLandmark(ILandmarkController landmark, MRFaceLandmark landmarkType)
        {
            // TODO: Investigate why we get calls to OnMatchLoss continuously after tracking loss
            if (m_AssignedFace == null)
            {
                return;
            }

            if (m_FallbackLandmarkPoses == null)
            {
                m_FallbackLandmarkPoses = MARSFallbackFaceLandmarks.instance.GetFallbackFaceLandmarkPoses();
            }

            Pose pose;

            if (m_AssignedFaceLandmarkPoses == null || !m_AssignedFaceLandmarkPoses.TryGetValue(landmarkType, out pose))
            {
                pose = m_AssignedFace.pose.ApplyOffsetTo(m_FallbackLandmarkPoses[landmarkType]);
            }

            var landmarkPose = landmark.output as LandmarkOutputPose;

            if (landmarkPose != null)
            {
                landmarkPose.currentPose = this.ApplyOffsetToPose(pose);
            }
        }
コード例 #4
0
        void CalculateBoundingRectFromExtents(ILandmarkController landmark)
        {
            if (!m_MRPlane.HasValue)
            {
                return;
            }

            var polygon = landmark.output as LandmarkOutputPolygon;

            if (polygon != null)
            {
                polygon.SetPolygonLocalSpace(m_BoundingRect, m_BoundingRectPose);
            }
        }
コード例 #5
0
        void CalculateCentroidLandmark(ILandmarkController landmark)
        {
            if (m_LocalVerts.Count < 1)
            {
                return;
            }

            var landmarkPoint = landmark.output as LandmarkOutputPoint;

            if (landmarkPoint != null)
            {
                landmarkPoint.position = pose.ApplyOffsetTo(GeometryUtils.PolygonCentroid2D(m_LocalVerts));
            }
        }
コード例 #6
0
        void CalculateCenter(ILandmarkController landmark)
        {
            if (!m_MRPlane.HasValue)
            {
                return;
            }

            var point = landmark.output as LandmarkOutputPoint;

            if (point != null)
            {
                var realWorldCenter = m_MRPlane.Value.pose.ApplyOffsetTo(m_MRPlane.Value.center);
                point.position = this.ApplyOffsetToPosition(realWorldCenter);
            }
        }
コード例 #7
0
        public void SetupLandmark(ILandmarkController landmark)
        {
            var faceLandmark = landmark.landmarkDefinition.GetEnumName <MRFaceLandmark>();

            if (m_FallbackLandmarkPoses == null)
            {
                m_FallbackLandmarkPoses = MARSFallbackFaceLandmarks.instance.GetFallbackFaceLandmarkPoses();
            }

            var initialPose = m_FallbackLandmarkPoses[faceLandmark];

            initialPose.position *= MARSSession.GetWorldScale();
            var landmarkTransform = ((Component)(landmark)).transform;

            landmarkTransform.SetLocalPose(initialPose);
            var landmarkPose = landmark.output as LandmarkOutputPose;

            if (landmarkPose != null)
            {
                landmarkPose.currentPose = landmarkTransform.GetWorldPose();
            }
        }
コード例 #8
0
        void CalculateClosestLandmark(ILandmarkController landmark)
        {
            var settings = landmark.settings as ClosestLandmarkSettings;

            if (settings == null)
            {
                return;
            }

            if (worldVertices == null || settings.target == null)
            {
                return;
            }

            if (m_WorldVerts.Count < 3)
            {
                return;
            }

            Vector3 edgeVertA;
            Vector3 edgeVertB;

            switch (landmark.output)
            {
            case LandmarkOutputPoint landmarkPoint:
            {
                var targetPolygon = settings.target as LandmarkOutputPolygon;
                if (targetPolygon && targetPolygon.worldVertices.Count > 0)
                {
                    Vector3 closestOnThis, closestOnOther;
                    GeometryUtils.ClosestPolygonApproach(m_WorldVerts, targetPolygon.worldVertices, out closestOnThis, out closestOnOther);
                    landmarkPoint.position = closestOnThis;
                }
                else
                {
                    var targetPosition       = settings.target.transform.position;
                    var planeNormal          = Vector3.Cross(m_WorldVerts[0] - m_WorldVerts[1], m_WorldVerts[2] - m_WorldVerts[1]).normalized;
                    var pointOnInfinitePlane = GeometryUtils.ProjectPointOnPlane(planeNormal, m_WorldVerts[1], targetPosition);
                    if (GeometryUtils.PointInPolygon3D(pointOnInfinitePlane, m_WorldVerts))
                    {
                        landmarkPoint.position = pointOnInfinitePlane;
                    }
                    else
                    {
                        GeometryUtils.FindClosestEdge(m_WorldVerts, targetPosition, out edgeVertA, out edgeVertB);
                        landmarkPoint.position = GeometryUtils.ClosestPointOnLineSegment(targetPosition, edgeVertA, edgeVertB);
                    }
                }
            }
            break;

            case LandmarkOutputEdge landmarkEdge:
            {
                var targetPosition = settings.target.transform.position;
                GeometryUtils.FindClosestEdge(m_WorldVerts, targetPosition, out edgeVertA, out edgeVertB);
                landmarkEdge.startPoint = edgeVertA;
                landmarkEdge.endPoint   = edgeVertB;
            }
            break;

            case LandmarkOutputPose landmarkPose:
            {
                var     targetPolygon = settings.target as LandmarkOutputPolygon;
                Vector3 closestOnThis, closestOnOther;

                if (targetPolygon && targetPolygon.worldVertices.Count > 0)
                {
                    GeometryUtils.ClosestPolygonApproach(m_WorldVerts, targetPolygon.worldVertices, out closestOnThis, out closestOnOther);
                }
                else
                {
                    closestOnOther = settings.target.transform.position;
                    var planeNormal          = Vector3.Cross(m_WorldVerts[0] - m_WorldVerts[1], m_WorldVerts[2] - m_WorldVerts[1]).normalized;
                    var pointOnInfinitePlane = GeometryUtils.ProjectPointOnPlane(planeNormal, m_WorldVerts[1], closestOnOther);
                    if (GeometryUtils.PointInPolygon3D(pointOnInfinitePlane, m_WorldVerts))
                    {
                        closestOnThis = pointOnInfinitePlane;
                    }
                    else
                    {
                        GeometryUtils.FindClosestEdge(m_WorldVerts, closestOnOther, out edgeVertA, out edgeVertB);
                        closestOnThis = GeometryUtils.ClosestPointOnLineSegment(closestOnOther, edgeVertA, edgeVertB);
                    }
                }
                // Make sure look direction is flattened along the plane
                var lookDirection = closestOnOther - closestOnThis;
                lookDirection            = Vector3.Cross(Vector3.Cross(lookDirection, transform.up), transform.up);
                landmarkPose.currentPose = new Pose {
                    position = closestOnThis, rotation = Quaternion.LookRotation(lookDirection)
                };
            }
            break;
            }
        }