Example #1
0
    // 1 - Query for visibility.
    // 2 - Determine if visibility state is new.
    // 3 - If visible, calculate marker pose.
    // 4 - If visible, set marker pose.
    // 5 - If visibility state is new, notify event receivers via "OnMarkerFound" or "OnMarkerLost".
    // 6 - If visibility state is new, set appropriate active state for marker children.
    // 7 - If visible, notify event receivers that the marker's pose has been updated via "OnMarkerTracked".
    protected virtual void LateUpdate()
    {
        if (!Application.isPlaying)
        {
            return;
        }

        float[] matrixRawArray = new float[16];
        lock (loadLock) {
            if (UID == NO_ID || !PluginFunctions.inited)
            {
                visible = false;
                return;
            }

            Vector3 storedScale = transform.localScale;
            transform.localScale = Vector3.one;

            // 1 - Query for visibility.
            bool nowVisible = PluginFunctions.arwQueryMarkerTransformation(UID, matrixRawArray);

            // 2 - Determine if visibility state is new.
            bool notify = (nowVisible != visible);
            visible = nowVisible;

            // 3 - If visible, calculate marker pose.
            if (visible)
            {
                // Scale the position from ARToolKit units (mm) into Unity units (m).
                matrixRawArray[12] *= UNITY_TO_ARTOOLKIT;
                matrixRawArray[13] *= UNITY_TO_ARTOOLKIT;
                matrixRawArray[14] *= UNITY_TO_ARTOOLKIT;

                Matrix4x4 matrixRaw = ARUtilityFunctions.MatrixFromFloatArray(matrixRawArray);
                // ARToolKit uses right-hand coordinate system where the marker lies in x-y plane with right in direction of +x,
                // up in direction of +y, and forward (towards viewer) in direction of +z.
                // Need to convert to Unity's left-hand coordinate system where marker lies in x-y plane with right in direction of +x,
                // up in direction of +y, and forward (towards viewer) in direction of -z.
                transformationMatrix = ARUtilityFunctions.LHMatrixFromRHMatrix(matrixRaw);

                // 4 - If visible, set marker pose.
                Matrix4x4 pose = ARStaticCamera.Instance.transform.localToWorldMatrix * transformationMatrix;
                transform.position   = ARUtilityFunctions.PositionFromMatrix(pose);
                transform.rotation   = ARUtilityFunctions.RotationFromMatrix(pose);
                transform.localScale = storedScale;
            }

            // 5 - If visibility state is new, notify event receivers via "OnMarkerFound" or "OnMarkerLost".
            if (notify)
            {
                if (null != eventReceivers && eventReceivers.Count > 0)
                {
                    if (visible)
                    {
                        eventReceivers.ForEach(x => x.OnMarkerFound(this));
                    }
                    else
                    {
                        eventReceivers.ForEach(x => x.OnMarkerLost(this));
                    }
                }
                // 6 - If visibility state is new, set appropriate active state for marker children.
                for (int i = 0; i < transform.childCount; ++i)
                {
                    transform.GetChild(i).gameObject.SetActive(visible);
                }
            }

            if (visible)
            {
                // 7 - If visible, notify event receivers that the marker's pose has been updated via "OnMarkerTracked".
                if (null != eventReceivers && eventReceivers.Count > 0)
                {
                    eventReceivers.ForEach(x => x.OnMarkerTracked(this));
                }
            }
        }
    }