// 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)); } } } }