示例#1
0
    private void copyToStreamingAssets(String path)
    {
        String fileName    = path.Substring(path.LastIndexOf('/') + 1);
        String destination = Application.streamingAssetsPath + "/" + ARToolKitAssetManager.IMAGES_DIRECTORY_NAME + "/" + fileName;

        //Check type of file to be .jpg or .jpeg
        if (fileName.Contains(".jpg") || fileName.Contains(".jpeg"))
        {
            ARController.Log("Copy image from: " + path + " to: " + destination);
            if (!File.Exists(destination))
            {
                FileUtil.CopyFileOrDirectory(path, destination);
                AssetDatabase.Refresh();
                ARToolKitAssetManager.Reload();
            }
            else
            {
                Debug.logger.Log(LogType.Error, "File with name: " + fileName + " already exists at destination: " + destination);
            }
        }
        else
        {
            //Dropped file is not a valid format print a warning\
            Debug.logger.Log(LogType.Warning, "<color=red>Item with invalid extension dropped. Only .jpg and .jpeg allowed.</color>");
        }
    }
示例#2
0
    // Get the trackable, if any, currently acting as the base.
    public ARTrackable GetBaseTrackable()
    {
        if (baseTrackable != null)
        {
            if (baseTrackable.Visible)
            {
                return(baseTrackable);
            }
            else
            {
                baseTrackable = null;
            }
        }
        foreach (ARTrackable m in trackablesEligibleForBaseTrackable)
        {
            if (m.Visible)
            {
                baseTrackable = m;
                ARController.Log("Trackable " + m.UID + " became base trackable.");
                break;
            }
        }

        return(baseTrackable);
    }
    public static void OnPostProcessBuild(BuildTarget target, string appPath)
    {
        string[] pathSplit     = appPath.Split('/');
        string   fileName      = pathSplit[pathSplit.Length - 1];
        string   pathDirectory = appPath.TrimEnd(fileName.ToCharArray());

        ARController.Log(string.Format(FILE_NAME_STATUS, fileName));
        fileName = fileName.Trim(EXE.ToCharArray());

        string fromPath = Path.Combine(pathDirectory, string.Format(RELATIVE_PATH, fileName));

        if (Directory.Exists(string.Format(RELATIVE_PATH, fileName)))
        {
            ARController.Log("ARTOOLKIT BUILD ERROR: Couldn't data directory!. Please move DLLs from [appname]_data/Plugins to the same directory as the exe!");
            return;
        }

        // Error when copying to remote drives.
        if (fromPath.StartsWith("//"))
        {
            fromPath = fromPath.Remove(0, 1);
        }

        foreach (string redistFile in REDIST_FILES)
        {
            File.Move(Path.Combine(fromPath, redistFile), Path.Combine(pathDirectory, redistFile));
        }
    }
示例#4
0
    public bool SetupCamera(float nearClipPlane, float farClipPlane, Matrix4x4 projectionMatrix, ref bool opticalOut)
    {
        Camera c = this.gameObject.GetComponent <Camera>();

        // A perspective projection matrix from the tracker
        c.orthographic = false;

        // Shouldn't really need to set these, because they are part of the custom
        // projection matrix, but it seems that in the editor, the preview camera view
        // isn't using the custom projection matrix.
        c.nearClipPlane = nearClipPlane;
        c.farClipPlane  = farClipPlane;

        if (Optical)
        {
            float   fovy;
            float   aspect;
            float[] m = new float[16];
            float[] p = new float[16];
            opticalSetupOK = PluginFunctions.arwLoadOpticalParams(null, OpticalParamsFileContents, OpticalParamsFileContents.Length, out fovy, out aspect, m, p);
            if (!opticalSetupOK)
            {
                ARController.Log(LogTag + "Error loading optical parameters.");
                return(false);
            }
            m[12] *= 0.001f;
            m[13] *= 0.001f;
            m[14] *= 0.001f;
            ARController.Log(LogTag + "Optical parameters: fovy=" + fovy + ", aspect=" + aspect + ", camera position (m)={" + m[12].ToString("F3") + ", " + m[13].ToString("F3") + ", " + m[14].ToString("F3") + "}");

            c.projectionMatrix = ARUtilityFunctions.MatrixFromFloatArray(p);

            opticalViewMatrix = ARUtilityFunctions.MatrixFromFloatArray(m);
            if (OpticalEyeLateralOffsetRight != 0.0f)
            {
                opticalViewMatrix = Matrix4x4.TRS(new Vector3(-OpticalEyeLateralOffsetRight, 0.0f, 0.0f), Quaternion.identity, Vector3.one) * opticalViewMatrix;
            }
            // Convert to left-hand matrix.
            opticalViewMatrix = ARUtilityFunctions.LHMatrixFromRHMatrix(opticalViewMatrix);

            opticalOut = true;
        }
        else
        {
            c.projectionMatrix = projectionMatrix;
        }

        // Don't clear anything or else we interfere with other foreground cameras
        c.clearFlags = CameraClearFlags.Nothing;

        // Renders after the clear and background cameras
        c.depth = 2;

        c.transform.position   = new Vector3(0.0f, 0.0f, 0.0f);
        c.transform.rotation   = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
        c.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);


        return(true);
    }
示例#5
0
        /// <summary>
        /// Called when the user denies camera permissions in response to CheckCameraPermissions() or RequestCameraPermissions().
        /// </summary>
        /// <param name="message">(unused)</param>
        void OnCameraPermissionDenied(string message)
        {
            ARController.Log("=====>> Warning: Camera permissions denied.");

            if (ShouldDisplayCameraPermissionsRationale())
            {
                DisplayCameraPermissionsRationale();
            }
        }
示例#6
0
        private bool CheckCameraPermissions(string gameObject)
        {
            if (!isAndroidMarshmallow())
            {
                return(true);
            }

            ARController.Log(LogTag + "CheckCameraPermissions called.");
            return(this.androidPlugin.Call <bool>("checkCameraPermissions", gameObject));
        }
 public static Quaternion QuaternionFromMatrix(Matrix4x4 m)
 {
     // Trap the case where the matrix passed in has an invalid rotation submatrix.
     if (m.GetColumn(2) == Vector4.zero)
     {
         ARController.Log("QuaternionFromMatrix got zero matrix.");
         return(Quaternion.identity);
     }
     return(Quaternion.LookRotation(m.GetColumn(2), m.GetColumn(1)));
 }
示例#8
0
 private void Awake()
 {
     if (null == instance)
     {
         instance = this;
     }
     else
     {
         ARController.Log("ERROR: MORE THAN ONE ARSTATICCAMERA IN SCENE!");
     }
 }
示例#9
0
        private bool isAndroidMarshmallow()
        {
#if !UNITY_EDITOR
            int version = this.androidPlugin.Call <int>("getAndroidVersion");
            ARController.Log(LogTag + "Android SDK version: " + version);

            return(version >= AndroidMarshmallow);
#else
            return(false);
#endif
        }
示例#10
0
    static ARToolKitMenuEditor()
    {
        if (EditorPrefs.GetBool(FIRST_RUN, true))
        {
            EditorPrefs.SetBool(FIRST_RUN, false);
            ARController.Log(string.Format(GET_TOOLS_MESSAGE, TOOLS_MENU_PATH));
#if UNITY_EDITOR_WIN
            ARController.Log(string.Format(WINDOWS_UNITY_MESSAGE, TOOLS_MENU_PATH));
#endif
        }
    }
示例#11
0
 public void FindMarkers()
 {
     RemoveAllMarkers();
     if (findMarkerMode != FindMode.Manual)
     {
         ARMarker[] ms = FindObjectsOfType <ARMarker>();            // Does not find inactive objects.
         foreach (ARMarker m in ms)
         {
             if (findMarkerMode == FindMode.AutoAll || (findMarkerMode == FindMode.AutoByTags && findMarkerTags.Contains(m.Tag)))
             {
                 markersEligibleForBaseMarker.Add(m);
             }
         }
         ARController.Log(LogTag + "Found " + markersEligibleForBaseMarker.Count + " markers eligible to become base marker.");
     }
 }
示例#12
0
 public void FindTrackables()
 {
     RemoveAllTrackables();
     if (findTrackableMode != FindMode.Manual)
     {
         ARTrackable[] ms = FindObjectsOfType <ARTrackable>();            // Does not find inactive objects.
         foreach (ARTrackable m in ms)
         {
             if (findTrackableMode == FindMode.AutoAll || (findTrackableMode == FindMode.AutoByTags && findTrackableTags.Contains(m.Tag)))
             {
                 trackablesEligibleForBaseTrackable.Add(m);
             }
         }
         ARController.Log(LogTag + "Found " + trackablesEligibleForBaseTrackable.Count + " trackables eligible to become base trackable.");
     }
 }
示例#13
0
 private bool unpackStreamingAssetToCacheDir(string basename)
 {
     if (!File.Exists(System.IO.Path.Combine(Application.temporaryCachePath, basename)))
     {
         string file        = System.IO.Path.Combine(Application.streamingAssetsPath, basename);      // E.g. "jar:file://" + Application.dataPath + "!/assets/" + basename;
         WWW    unpackerWWW = new WWW(file);
         while (!unpackerWWW.isDone)
         {
         }                                           // This will block in the webplayer. TODO: switch to co-routine.
         if (!string.IsNullOrEmpty(unpackerWWW.error))
         {
             ARController.Log(LogTag + "Error unpacking '" + file + "'");
             return(false);
         }
         File.WriteAllBytes(System.IO.Path.Combine(Application.temporaryCachePath, basename), unpackerWWW.bytes);             // 64MB limit on File.WriteAllBytes.
     }
     return(true);
 }
示例#14
0
    // We use Update() here, but be aware that unless ARController has been configured to
    // execute first (Unity Editor->Edit->Project Settings->Script Execution Order) then
    // state produced by this update may lag by one frame.
    void Update()
    {
        float[] matrixRawArray = new float[16];

        ARController.Log(LogTag + "ARMarker.Update()");
        if (UID == NO_ID || !PluginFunctions.inited)
        {
            visible = false;
            return;
        }

        // Query visibility if we are running in the Player.
        if (Application.isPlaying)
        {
            visible = PluginFunctions.arwQueryMarkerTransformation(UID, matrixRawArray);
            ARController.Log(LogTag + "ARMarker.Update() UID=" + UID + ", visible=" + visible);

            if (visible)
            {
                matrixRawArray[12] *= 0.001f;                 // Scale the position from ARToolKit units (mm) into Unity units (m).
                matrixRawArray[13] *= 0.001f;
                matrixRawArray[14] *= 0.001f;

                Matrix4x4 matrixRaw = ARUtilityFunctions.MatrixFromFloatArray(matrixRawArray);
                //ARController.Log("arwQueryMarkerTransformation(" + UID + ") got matrix: [" + Environment.NewLine + matrixRaw.ToString("F3").Trim() + "]");

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

                // Output current position: Added by Kazu on Apr 2 2016
                Vector3 position = ARUtilityFunctions.PositionFromMatrix(transformationMatrix);
                print("Position of Barcode ID #" + BarcodeID + ": (" + position.x * 1000 + ", " + position.y * 1000 + ", " + position.z * 1000 + ")");
//				print ("position.x [mm]: "+ position.x * 1000);
//				print ("position.y [mm]: "+ position.y * 1000);
//				print ("position.z [mm]: "+ position.z * 1000);
//				If you need quaternion, you can use the followings.
//				Quaternion orientation = ARUtilityFunctions.QuaternionFromMatrix(transformationMatrix);
            }
        }
    }
示例#15
0
    public static bool GetFileFromStreamingAssets(string relative, out string desination)
    {
        desination = Path.Combine(Application.streamingAssetsPath, relative);
        ARController.Log("GetFileFromStreamingAssets(): destination: " + desination);
#if !UNITY_METRO
        // On Android, we need to unpack the StreamingAssets from the .jar file in which
        // they're archived into the native file system.
        // URIs are valid whether we're using an absolute path or not.
        // Check specifically for URL-like scheme.
        if (desination.Contains("://"))
        {
            // E.g. "jar:file://" + Application.dataPath + "!/assets/" + basename;
            string source = desination;
            desination = Path.Combine(Application.temporaryCachePath, relative);
            // File has already been unpacked. Skip.
            // TODO: Add some integrity checking that it's the right file.
            if (File.Exists(desination))
            {
                ARController.Log("File already exists at destination: " + desination);
                return(true);
            }
            WWW www = new WWW(source);
            // This will block in the webplayer.
            // TODO: switch to co-routine.
            while (!www.isDone)
            {
                ;
            }
            if (!string.IsNullOrEmpty(www.error))
            {
                ARController.Log(string.Format(UNPACK_ERROR, source, desination));
                desination = string.Empty;
                return(false);
            }
            // Note: 64MB limit on File.WriteAllBytes.
            // TODO: Verify limit.
            Directory.CreateDirectory(desination.Substring(0, desination.LastIndexOf('/')));
            File.WriteAllBytes(desination, www.bytes);
        }
#endif
        return(true);
    }
示例#16
0
        void OnApplicationFocus(bool focus)
        {
            if (!focus)
            {
                return;
            }

            ARController.Log("ARToolKit has just regained focus.");
            #if UNITY_ANDROID && !UNITY_EDITOR
            if (androidPlugin == null)
            {
                connectToAndroidPlugin();
            }
            #endif

            if (ShouldDisplayCameraPermissionsRationale())
            {
                DisplayCameraPermissionsRationale();
            }
        }
示例#17
0
 private void connectToAndroidPlugin()
 {
     ARController.Log(LogTag + "About to initialize the Android Plugin");
     using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer")){
         if (jc != null)
         {
             using (AndroidJavaObject activity = jc.GetStatic <AndroidJavaObject> ("currentActivity")) {
                 androidPlugin = activity.Call <AndroidJavaObject> ("getARToolKitPlugin");
                 if (null == androidPlugin)
                 {
                     ARController.Log(LogTag + "ERROR: Could not connect to ARToolKit-Android plugin! Are we missing ar6jUnity.jar?");
                 }
                 else
                 {
                     androidPlugin.Call("unityIsUp", new object[] { true });
                 }
             }
         }
     }
 }
示例#18
0
    void Start()
    {
        ARController.Log(LogTag + "Start()");
        secondsToRemainVisible = 0.0f;

        if (Application.isPlaying)
        {
            // In Player, set initial visibility to not visible.
            for (int i = 0; i < this.transform.childCount; i++)
            {
                this.transform.GetChild(i).gameObject.SetActive(false);
            }
        }
        else
        {
            // In Editor, set initial visibility to visible.
            for (int i = 0; i < this.transform.childCount; i++)
            {
                this.transform.GetChild(i).gameObject.SetActive(true);
            }
        }
    }
示例#19
0
        /// <summary>
        /// Confirms that the application has camera permissions, requesting them if necessary.
        /// </summary>
        public void ConfirmCameraPermissions()
        {
#if USAGE_EXAMPLE
            if (HasCameraPermissions())
            {
                ARController.Log("ARToolKit has camera permissions.");
            }
            else
            {
                ARController.Log("Warning: ARToolKit does not have camera permissions!");
            }
#endif

#if !UNITY_EDITOR && UNITY_ANDROID
            if (CheckCameraPermissions(gameObject.name))
            {
                ARController.Log("ARToolKit already has camera permissions.");
            }
            else
            {
                ARController.Log("ARToolKit is requesting camera permissions.");
            }
#endif

#if USAGE_EXAMPLE
            RequestCameraPermissions(gameObject.name);
#endif

            if (ShouldDisplayCameraPermissionsRationale())
            {
                ARController.Log("ARToolKit should explain camera permission rationale.");
            }
            else
            {
                ARController.Log("ARToolKit does not need to explain camera permission rationale.");
            }
        }
示例#20
0
    // Load the underlying ARToolKit marker structure(s) and set the UID.
    public void Load()
    {
        //ARController.Log(LogTag + "ARMarker.Load()");
        if (UID != NO_ID)
        {
            //ARController.Log(LogTag + "Marker already loaded.");
            return;
        }

        if (!PluginFunctions.inited)
        {
            return;
        }

        // Work out the configuration string to pass to ARToolKit.
        string dir = Application.streamingAssetsPath;
        string cfg = "";

        switch (MarkerType)
        {
        case MarkerType.Square:
            // Multiply width by 1000 to convert from metres to ARToolKit's millimetres.
            cfg = "single_buffer;" + PatternWidth * 1000.0f + ";buffer=" + PatternContents;
            break;

        case MarkerType.SquareBarcode:
            // Multiply width by 1000 to convert from metres to ARToolKit's millimetres.
            cfg = "single_barcode;" + BarcodeID + ";" + PatternWidth * 1000.0f;
            break;

        case MarkerType.Multimarker:
                                #if !UNITY_METRO
            if (dir.Contains("://"))
            {
                // On Android, we need to unpack the StreamingAssets from the .jar file in which
                // they're archived into the native file system.
                dir = Application.temporaryCachePath;
                if (!unpackStreamingAssetToCacheDir(MultiConfigFile))
                {
                    dir = "";
                }
                else
                {
                    //string[] unpackFiles = getPatternFiles;
                    //foreach (string patternFile in patternFiles) {
                    //if (!unpackStreamingAssetToCacheDir(patternFile)) {
                    //    dir = "";
                    //    break;
                    //}
                }
            }
                                #endif

            if (!string.IsNullOrEmpty(dir) && !string.IsNullOrEmpty(MultiConfigFile))
            {
                cfg = "multi;" + System.IO.Path.Combine(dir, MultiConfigFile);
            }
            break;


        case MarkerType.NFT:
                                #if !UNITY_METRO
            if (dir.Contains("://"))
            {
                // On Android, we need to unpack the StreamingAssets from the .jar file in which
                // they're archived into the native file system.
                dir = Application.temporaryCachePath;
                foreach (string ext in NFTDataExts)
                {
                    string basename = NFTDataName + "." + ext;
                    if (!unpackStreamingAssetToCacheDir(basename))
                    {
                        dir = "";
                        break;
                    }
                }
            }
                                #endif

            if (!string.IsNullOrEmpty(dir) && !string.IsNullOrEmpty(NFTDataName))
            {
                cfg = "nft;" + System.IO.Path.Combine(dir, NFTDataName);
            }
            break;

        default:
            // Unknown marker type?
            break;
        }

        // If a valid config. could be assembled, get ARToolKit to process it, and assign the resulting ARMarker UID.
        if (!string.IsNullOrEmpty(cfg))
        {
            UID = PluginFunctions.arwAddMarker(cfg);
            if (UID == NO_ID)
            {
                ARController.Log(LogTag + "Error loading marker.");
            }
            else
            {
                // Marker loaded. Do any additional configuration.
                //ARController.Log("Added marker with cfg='" + cfg + "'");

                if (MarkerType == MarkerType.Square || MarkerType == MarkerType.SquareBarcode)
                {
                    UseContPoseEstimation = currentUseContPoseEstimation;
                }
                Filtered         = currentFiltered;
                FilterSampleRate = currentFilterSampleRate;
                FilterCutoffFreq = currentFilterCutoffFreq;
                if (MarkerType == MarkerType.NFT)
                {
                    NFTScale = currentNFTScale;
                }

                // Retrieve any required information from the configured ARToolKit ARMarker.
                if (MarkerType == MarkerType.NFT)
                {
                    int imageSizeX, imageSizeY;
                    PluginFunctions.arwGetMarkerPatternConfig(UID, 0, null, out NFTWidth, out NFTHeight, out imageSizeX, out imageSizeY);
                    NFTWidth  *= 0.001f;
                    NFTHeight *= 0.001f;
                    //ARController.Log("Got NFTWidth=" + NFTWidth + ", NFTHeight=" + NFTHeight + ".");
                }
                else
                {
                    // Create array of patterns. A single marker will have array length 1.
                    int numPatterns = PluginFunctions.arwGetMarkerPatternCount(UID);
                    //ARController.Log("Marker with UID=" + UID + " has " + numPatterns + " patterns.");
                    if (numPatterns > 0)
                    {
                        patterns = new ARPattern[numPatterns];
                        for (int i = 0; i < numPatterns; i++)
                        {
                            patterns[i] = new ARPattern(UID, i);
                        }
                    }
                }
            }
        }
    }
示例#21
0
    // Load the underlying ARToolKit marker structure(s) and set the UID.
    public void Load()
    {
        lock (loadLock) {
            if (UID != NO_ID)
            {
                return;
            }
            if (!PluginFunctions.inited)
            {
                // If arwInitialiseAR() has not yet been called, we can't load the native trackable yet.
                // ARController.InitialiseAR() will call this again when arwInitialiseAR() has been called.
                return;
            }
            // Work out the configuration string to pass to ARToolKit.
            string assetDirectory = Application.streamingAssetsPath;
            string configuration  = string.Empty;
            string path           = string.Empty;

            switch (Type)
            {
            case TrackableType.TwoD:
                if (string.IsNullOrEmpty(TwoDImageName))
                {
                    ARController.Log(string.Format(LOAD_FAILURE, "2D image trackable due to no TwoDImageName"));
                    return;
                }
                path = Path.Combine(TWOD_FORMAT, TwoDImageName);
                if (!ARUtilityFunctions.GetFileFromStreamingAssets(path, out assetDirectory))
                {
                    ARController.Log(string.Format(LOAD_FAILURE, TwoDImageName));
                    return;
                }
                if (!string.IsNullOrEmpty(assetDirectory))
                {
                    configuration = string.Format(TWOD_CONFIG, assetDirectory, TwoDImageHeight * ARTOOLKIT_TO_UNITY);
                }
                break;

            case TrackableType.Square:
                // Multiply width by 1000 to convert from metres to ARToolKit's millimetres.
                configuration = string.Format(SINGLE_BUFFER_CONFIG, PatternWidth * ARTOOLKIT_TO_UNITY, PatternContents);
                break;

            case TrackableType.SquareBarcode:
                // Multiply width by 1000 to convert from metres to ARToolKit's millimetres.
                configuration = string.Format(SINGLE_BARCODE_CONFIG, BarcodeID, PatternWidth * ARTOOLKIT_TO_UNITY);
                break;

            case TrackableType.Multimarker:
                if (string.IsNullOrEmpty(MultiConfigFile))
                {
                    ARController.Log(string.Format(LOAD_FAILURE, "multimarker due to no MultiConfigFile"));
                    return;
                }
                path = Path.Combine(MULTI_FORMAT, MultiConfigFile + MULTI_EXT);
                ARUtilityFunctions.GetFileFromStreamingAssets(path, out assetDirectory);
                if (!string.IsNullOrEmpty(assetDirectory))
                {
                    configuration = string.Format(MULTI_CONFIG, assetDirectory);
                }
                break;

            default:
                // Unknown marker type?
                ARController.Log(string.Format(LOAD_FAILURE, "due to unknown marker"));
                return;
            }

            // If a valid config. could be assembled, get ARToolKit to process it, and assign the resulting ARMarker UID.
            if (string.IsNullOrEmpty(configuration))
            {
                ARController.Log(LOG_TAG + "trackable configuration is null or empty.");
                return;
            }

            uid = PluginFunctions.arwAddMarker(configuration);
            if (UID == NO_ID)
            {
                ARController.Log(LOG_TAG + "Error loading trackable.");
                return;
            }

            // Trackable loaded. Do any additional configuration.
            if (Type == TrackableType.Square || Type == TrackableType.SquareBarcode)
            {
                UseContPoseEstimation = currentUseContPoseEstimation;
            }

            Filtered         = currentFiltered;
            FilterSampleRate = currentFilterSampleRate;
            FilterCutoffFreq = currentFilterCutoffFreq;

            // Retrieve any required information from the configured ARTrackable.
            if (Type == TrackableType.TwoD)
            {
                int   dummyImageSizeX, dummyImageSizeY;
                float dummyTwoDImageHeight;
                PluginFunctions.arwGetTrackableAppearanceConfig(UID, 0, null, out TwoDImageWidth, out dummyTwoDImageHeight, out dummyImageSizeX, out dummyImageSizeY);
                TwoDImageWidth *= UNITY_TO_ARTOOLKIT;
            }
            else
            {
                // Create array of patterns. A single marker will have array length 1.
                int numPatterns = PluginFunctions.arwGetTrackableAppearanceCount(UID);
                if (numPatterns > 0)
                {
                    patterns = new ARPattern[numPatterns];
                    for (int i = 0; i < numPatterns; ++i)
                    {
                        patterns[i] = new ARPattern(UID, i);
                    }
                }
            }
        }
    }
示例#22
0
 public void DisplayCameraPermissionsRationale()
 {
     ARController.Log("Displaying camera permissions rationale view.");
     //TODO: implement view
 }
示例#23
0
 /// <summary>
 /// Called when the user grants camera permissions in response to CheckCameraPermissions() or RequestCameraPermissions().
 /// </summary>
 /// <param name="message">(unused)</param>
 void OnCameraPermissionGranted(string message)
 {
     ARController.Log("=====>> Camera permissions granted.");
 }
示例#24
0
    // Use LateUpdate to be sure the ARMarker has updated before we try and use the transformation.
    void LateUpdate()
    {
        // Local scale is always 1 for now
        transform.localScale = Vector3.one;

        // Update tracking if we are running in the Player.
        if (Application.isPlaying)
        {
            // Sanity check, make sure we have an AROrigin in parent hierachy.
            AROrigin origin = GetOrigin();
            if (origin == null)
            {
                ARController.Log(LogTag + "No Origin");
                //visible = visibleOrRemain = false;
            }
            else
            {
                // Sanity check, make sure we have an ARMarker assigned.
                ARMarker marker = GetMarker();
                if (marker == null)
                {
                    ARController.Log(LogTag + "No ARMarker");
                    //visible = visibleOrRemain = false;
                }
                else
                {
                    // Note the current time
                    float timeNow = Time.realtimeSinceStartup;

                    ARMarker baseMarker = origin.GetBaseMarker();
                    if (baseMarker != null && marker.Visible)
                    {
                        if (!visible)
                        {
                            // Marker was hidden but now is visible.
                            ARController.Log(LogTag + "Marker was hidden but now is visible.");
                            visible = visibleOrRemain = true;
                            if (eventReceiver != null)
                            {
                                eventReceiver.BroadcastMessage("OnMarkerFound", marker, SendMessageOptions.DontRequireReceiver);
                            }

                            for (int i = 0; i < this.transform.childCount; i++)
                            {
                                this.transform.GetChild(i).gameObject.SetActive(true);
                            }
                        }
                        else
                        {
//							ARController.Log (LogTag + "Marker stayed visible");
                        }

                        Matrix4x4 pose;
                        if (marker == baseMarker)
                        {
                            // If this marker is the base, no need to take base inverse etc.
                            pose = origin.transform.localToWorldMatrix;
                        }
                        else
                        {
                            pose = (origin.transform.localToWorldMatrix * baseMarker.TransformationMatrix.inverse * marker.TransformationMatrix);
                        }
                        transform.position = ARUtilityFunctions.PositionFromMatrix(pose);
                        transform.rotation = ARUtilityFunctions.QuaternionFromMatrix(pose);

                        if (eventReceiver != null)
                        {
                            eventReceiver.BroadcastMessage("OnMarkerTracked", marker, SendMessageOptions.DontRequireReceiver);
                        }
                    }
                    else
                    {
                        if (visible)
                        {
                            // Marker was visible but now is hidden.
                            ARController.Log(LogTag + "Marker was visible but now is hidden. (after " + secondsToRemainVisible + "s)");
                            visible          = false;
                            timeTrackingLost = timeNow;
                        }
                        else
                        {
//							ARControllertroller.Log (LogTag + "Marker stayed hidden.");
                        }

                        if (visibleOrRemain && (timeNow - timeTrackingLost >= secondsToRemainVisible))
                        {
                            visibleOrRemain = false;
                            if (eventReceiver != null)
                            {
                                eventReceiver.BroadcastMessage("OnMarkerLost", marker, SendMessageOptions.DontRequireReceiver);
                            }
                            for (int i = 0; i < this.transform.childCount; i++)
                            {
                                this.transform.GetChild(i).gameObject.SetActive(false);
                            }
                        }
                    }
                }  // marker
            }      // origin
        }          // Application.isPlaying
        else
        {
            ARController.Log(LogTag + "Applicaiton Not Playing");
        }
    }
示例#25
0
//	private Guid   cacheGuid               = Guid.Empty;
//	// When indexes update, there are three likely scenarios:
//	//     1) ID has not changed.
//	//     2) ID has shifted by a few values due to sorting.
//	//     3) Content has been removed, and therefore there is no ID.
//	private int ReassociateContentID(int index, TrackableType markerType, string content) {
//		if (string.CompareOrdinal(ARToolKitAssetManager.AllMarkers[index], content) == 0) {
//			return index;
//		} else {
//			for (int i = 0; i < ARToolKitAssetManager.
//		}
//	}

    public override void OnInspectorGUI()
    {
        // Get the ARMarker that this panel will edit.
        ARTrackable arMarker = (ARTrackable)target;

        if (null == arMarker)
        {
            return;
        }
        // Attempt to load. Might not work out if e.g. for a single marker, pattern hasn't been
        // assigned yet, or for an NFT marker, dataset hasn't been specified.
        if (arMarker.UID == ARTrackable.NO_ID)
        {
            PluginFunctions.arwInitialiseAR();
            arMarker.Load();
        }

        // Check if a new image was dropped into the Project directory
        string        path = Application.streamingAssetsPath + "/" + ARToolKitAssetManager.IMAGES_DIRECTORY_NAME;
        DirectoryInfo dir  = new DirectoryInfo(path);

        FileInfo[] imageFileList = dir.GetFiles("*.jpg").Union(dir.GetFiles("*.jpeg")).ToArray();
        if (imageFileList != null && ARToolKitAssetManager.Images != null && imageFileList.Length != ARToolKitAssetManager.Images.Length)
        {
            if (imageFileList.Length < ARToolKitAssetManager.Images.Length)
            {
                //An image was deleted from the file system so we might have an empty ARTrackable now
                ARController.Log("Warning: Trackable image removed. Please check all ARTrackables and make sure that they have an image assigned.");
            }
            //We found a new trackable in the file system or a trackable was removed lets reload the trackables.
            ARToolKitAssetManager.Reload();
        }

        // Draw the drag n drop area
        DropAreaGUI();

        int selectedMarker = ArrayUtility.IndexOf(ARToolKitAssetManager.AllMarkers, arMarker.EditorMarkerName);

        arMarker.EditorMarkerIndex = EditorGUILayout.Popup("Marker", selectedMarker, ARToolKitAssetManager.AllMarkers);

        bool newSelection = false;

        if (arMarker.EditorMarkerIndex < 0)
        {
            //An image was deleted from the file system so we have an empty ARTrackable now
            ARController.Log("Warning: Trackable image removed. Please check the ARTrackable and make sure that is has an image assigned.");
            return;
        }
        else
        {
            if (string.CompareOrdinal(arMarker.EditorMarkerName, ARToolKitAssetManager.AllMarkers[arMarker.EditorMarkerIndex]) != 0)
            {
                newSelection = true;
                arMarker.EditorMarkerName = ARToolKitAssetManager.AllMarkers[arMarker.EditorMarkerIndex];
            }
        }

        ARTrackable.TrackableType markerType = DetermineTrackableType(arMarker.EditorMarkerIndex);
        if (arMarker.Type != markerType)
        {
            arMarker.ClearUnusedValues();
            arMarker.Type = markerType;
            UpdatePatternDetectionMode();
        }

        EditorGUILayout.LabelField("Type ", ARTrackable.TrackableTypeNames[arMarker.Type]);

        EditorGUILayout.LabelField("Unique ID", (arMarker.UID == ARTrackable.NO_ID ? "Not Loaded": arMarker.UID.ToString()));

        EditorGUILayout.BeginHorizontal();
        // Draw all the marker images
        if (arMarker.Patterns != null)
        {
            for (int i = 0; i < arMarker.Patterns.Length; ++i)
            {
                EditorGUILayout.Separator();
                GUILayout.Label(new GUIContent(string.Format("Pattern {0}, {1}m", i, arMarker.Patterns[i].width.ToString("n3")), arMarker.Patterns[i].texture), GUILayout.ExpandWidth(false));                 // n3 -> 3 decimal places.
            }
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.Separator();

        switch (arMarker.Type)
        {
        case ARTrackable.TrackableType.TwoD:
            if (newSelection)
            {
                arMarker.TwoDImageName = ARToolKitAssetManager.AllMarkers[arMarker.EditorMarkerIndex];
            }
            float twoDImageHeight = EditorGUILayout.FloatField("Image height", arMarker.TwoDImageHeight);
            if (twoDImageHeight != arMarker.TwoDImageHeight)
            {
                EditorUtility.SetDirty(arMarker);
                arMarker.TwoDImageHeight = twoDImageHeight;
            }

            float   width = 0.0f, height = 0.0f;
            int     imageWidth = 0, imageHeight = 0;
            float[] transformation = new float[16];

            if (PluginFunctions.arwGetTrackableAppearanceConfig(arMarker.UID, 0, transformation, out width, out height, out imageWidth, out imageHeight))
            {
                Color32[] imagePixels = new Color32[imageWidth * imageHeight];
                if (PluginFunctions.arwGetTrackableAppearanceImage(arMarker.UID, 0, imagePixels))
                {
                    //Set the texture with the trackable appearance.
                    Texture2D texture = new Texture2D(imageWidth, imageHeight, TextureFormat.RGBA32, true);
                    texture.SetPixels32(imagePixels);
                    texture.Apply();

                    //Display label and texture to the user
                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Label("Trackable Appearance");

                    //Resize texture for viewport with max with and height
                    GUILayout.Label(ARTrackableAppearanceScale.BilinearWithMaxSize(texture, 200, 200));
                    EditorGUILayout.EndHorizontal();
                }
            }
            break;

        case ARTrackable.TrackableType.Square:
            if (newSelection)
            {
                arMarker.PatternContents = GetPatternContents(ARToolKitAssetManager.AllMarkers[arMarker.EditorMarkerIndex]);
            }
            arMarker.PatternWidth          = EditorGUILayout.FloatField("Pattern Width (m)", arMarker.PatternWidth);
            arMarker.UseContPoseEstimation = EditorGUILayout.Toggle("Contstant Pose Estimation", arMarker.UseContPoseEstimation);
            break;

        case ARTrackable.TrackableType.SquareBarcode:
            if (newSelection)
            {
                string[] idArray = ARToolKitAssetManager.AllMarkers[arMarker.EditorMarkerIndex].Split(' ');
                arMarker.BarcodeID = int.Parse(idArray[idArray.Length - 1]);
            }
            arMarker.PatternWidth          = EditorGUILayout.FloatField("Pattern Width (m)", arMarker.PatternWidth);
            arMarker.UseContPoseEstimation = EditorGUILayout.Toggle("Contstant Pose Estimation", arMarker.UseContPoseEstimation);
            break;

        case ARTrackable.TrackableType.Multimarker:
            if (newSelection)
            {
                arMarker.MultiConfigFile = ARToolKitAssetManager.AllMarkers[arMarker.EditorMarkerIndex];
            }
            break;
        }

        EditorGUILayout.Separator();

        arMarker.Filtered = EditorGUILayout.Toggle("Filter Pose", arMarker.Filtered);
        if (arMarker.Filtered)
        {
            arMarker.FilterSampleRate = EditorGUILayout.Slider("Sample Rate", arMarker.FilterSampleRate, 1.0f, 30.0f);
            arMarker.FilterCutoffFreq = EditorGUILayout.Slider("Cutoff Frequency", arMarker.FilterCutoffFreq, 1.0f, 30.0f);
        }

        if (arMarker.Type == ARTrackable.TrackableType.Square || arMarker.Type == ARTrackable.TrackableType.SquareBarcode || arMarker.Type == ARTrackable.TrackableType.Multimarker)
        {
            showGlobalSquareOptions = EditorGUILayout.Foldout(showGlobalSquareOptions, "Global Square Tracking Options");
            if (showGlobalSquareOptions)
            {
                ARController.Instance.TemplateSize = EditorGUILayout.IntSlider("Template Size (bits)", ARController.Instance.TemplateSize, 16, 64);

                int currentTemplateCountMax = ARController.Instance.TemplateCountMax;
                int newTemplateCountMax     = EditorGUILayout.IntField("Maximum Template Count", currentTemplateCountMax);
                if (newTemplateCountMax != currentTemplateCountMax && newTemplateCountMax > 0)
                {
                    ARController.Instance.TemplateCountMax = newTemplateCountMax;
                }

                bool trackInColor = EditorGUILayout.Toggle("Track Templates in Color", ARController.Instance.trackTemplatesInColor);
                if (trackInColor != ARController.Instance.trackTemplatesInColor)
                {
                    ARController.Instance.trackTemplatesInColor = trackInColor;
                    UpdatePatternDetectionMode();
                }

                ARController.Instance.BorderSize    = UnityEngine.Mathf.Clamp(EditorGUILayout.FloatField("Border Size (%)", ARController.Instance.BorderSize), 0.0f, 0.5f);
                ARController.Instance.LabelingMode  = (ARController.ARToolKitLabelingMode)EditorGUILayout.EnumPopup("Marker Border Color", ARController.Instance.LabelingMode);
                ARController.Instance.ImageProcMode = (ARController.ARToolKitImageProcMode)EditorGUILayout.EnumPopup("Image Processing Mode", ARController.Instance.ImageProcMode);
            }
        }

        var obj  = new SerializedObject(arMarker);
        var prop = obj.FindProperty("eventReceivers");

        EditorGUILayout.PropertyField(prop, new GUIContent("Event Receivers"), true);
        obj.ApplyModifiedProperties();
    }
    public static void OnPostProcessBuild(BuildTarget target, string pathToBuiltProject)
    {
        string logPath = Path.Combine(pathToBuiltProject, LOGFILE_NAME);

#if UNITY_4_5 || UNITY_4_6
        if (target != BuildTarget.iPhone)
        {
#else
        if (target != BuildTarget.iOS)
        {
#endif
            ARController.Log("Error: ARToolKitPostProcessor::OnIosPostProcess - Called on non iOS build target!");
            return;
        }
        else if (File.Exists(logPath))
        {
            streamWriter = new StreamWriter(logPath, true);
            streamWriter.WriteLine("OnIosPostProcess - Beginning iOS post-processing.");
            streamWriter.WriteLine("OnIosPostProcess - WARNING - Attempting to process directory that has already been processed. Skipping.");
            streamWriter.WriteLine("OnIosPostProcess - Aborted iOS post-processing.");
            streamWriter.Close();
            streamWriter = null;
        }
        else
        {
            streamWriter = new StreamWriter(logPath);
            streamWriter.WriteLine("OnIosPostProcess - Beginning iOS post-processing.");

            try {
                string pbxprojPath = Path.Combine(pathToBuiltProject, PBXJPROJ_FILE_PATH);
                if (File.Exists(pbxprojPath))
                {
                    string pbxproj = File.ReadAllText(pbxprojPath);

                    streamWriter.WriteLine("OnIosPostProcess - Modifying file at " + pbxprojPath);

                    string pbxBuildFile            = string.Empty;
                    string pbxFileReference        = string.Empty;
                    string pbxFrameworksBuildPhase = string.Empty;
                    string pbxGroup = string.Empty;
                    for (int i = 0; i < iosFrameworks.Length; ++i)
                    {
                        if (pbxproj.Contains(iosFrameworks[i].Path))
                        {
                            streamWriter.WriteLine("OnIosPostProcess - Project already contains reference to " + iosFrameworks[i].Name + " - skipping.");
                            continue;
                        }
                        pbxBuildFile     += string.Format(PBXBUILDFILE_STRING_FORMAT, new object[] { iosFrameworks[i].Id, iosFrameworks[i].Name, iosFrameworks[i].RefId });
                        pbxFileReference += string.Format(PBXFILEREFERENCE_STRING_FORMAT, new object[] { iosFrameworks[i].RefId, iosFrameworks[i].Name, iosFrameworks[i].LastKnownFileType,
                                                                                                         iosFrameworks[i].FormattedName, iosFrameworks[i].Path, iosFrameworks[i].SourceTree });
                        pbxFrameworksBuildPhase += string.Format(PBXFRAMEWORKSBUILDPHASE_STRING_FORMAT, new object[] { iosFrameworks[i].Id, iosFrameworks[i].Name });
                        pbxGroup += string.Format(PBXGROUP_STRING_FORMAT, new object[] { iosFrameworks[i].RefId, iosFrameworks[i].Name });
                        streamWriter.WriteLine("OnPostProcessBuild - Processed " + iosFrameworks[i].Name);
                    }

                    int index = pbxproj.IndexOf(PBXBUILDFILE_SECTION_END);
                    pbxproj = pbxproj.Insert(index, pbxBuildFile);
                    streamWriter.WriteLine("OnPostProcessBuild - Injected PBXBUILDFILE");

                    index   = pbxproj.IndexOf(PBXFILEREFERENCE_SECTION_END);
                    pbxproj = pbxproj.Insert(index, pbxFileReference);
                    streamWriter.WriteLine("OnPostProcessBuild - Injected PBXFILEREFERENCE");

                    index   = pbxproj.IndexOf(PBXFRAMEWORKSBUILDPHASE_SECTION_BEGIN);
                    index   = pbxproj.IndexOf(PBXFRAMEWORKSBUILDPHASE_SUBSET, index) + PBXFRAMEWORKSBUILDPHASE_SUBSET.Length;
                    pbxproj = pbxproj.Insert(index, pbxFrameworksBuildPhase);
                    streamWriter.WriteLine("OnPostProcessBuild - Injected PBXFRAMEWORKSBUILDPHASE");

                    index   = pbxproj.IndexOf(PBXGROUP_SECTION_BEGIN);
                    index   = pbxproj.IndexOf(PBXGROUP_SUBSET_1, index);
                    index   = pbxproj.IndexOf(PBXGROUP_SUBSET_2, index) + PBXGROUP_SUBSET_2.Length;
                    pbxproj = pbxproj.Insert(index, pbxGroup);
                    streamWriter.WriteLine("OnPostProcessBuild - Injected PBXGROUP");

                    pbxproj = pbxproj.Replace(ENABLE_BITCODE, DISABLE_BITCODE);
                    streamWriter.WriteLine("OnPostProcessBuild - Disabled Bitcode");

                    File.Delete(pbxprojPath);
                    File.WriteAllText(pbxprojPath, pbxproj);

                    streamWriter.WriteLine("OnIosPostProcess - Ending iOS post-processing successfully.");
                }
                else
                {
                    streamWriter.WriteLine("OnIosPostProcess - ERROR - File " + pbxprojPath + " does not exist!");
                }
            } catch (System.Exception e) {
                streamWriter.WriteLine("ProcessSection - ERROR - " + e.Message + " : " + e.StackTrace);
            } finally {
                streamWriter.Close();
                streamWriter = null;
            }
        }
    }
#endif
}
    public override void OnInspectorGUI()
    {
        ARStaticCamera arStaticCamera = (ARStaticCamera)target;

        if (null == arStaticCamera)
        {
            return;
        }

        arStaticCamera.ContentLayer = EditorGUILayout.LayerField("AR Content Layer", arStaticCamera.ContentLayer);
        arStaticCamera.NearPlane    = EditorGUILayout.FloatField("Near Plane", arStaticCamera.NearPlane);
        arStaticCamera.FarPlane     = EditorGUILayout.FloatField("Far Plane", arStaticCamera.FarPlane);
        EditorGUILayout.Separator();

        arStaticCamera.Stereo = EditorGUILayout.Toggle("Stereo Rendering", arStaticCamera.Stereo);

        if (ARToolKitAssetManager.OpticalCalibrations.Length <= 0)
        {
            arStaticCamera.Optical = false;
        }
        EditorGUI.BeginDisabledGroup(ARToolKitAssetManager.OpticalCalibrations.Length <= 0);
        arStaticCamera.Optical = EditorGUILayout.Toggle("Optical See-Through Display", arStaticCamera.Optical);
        EditorGUI.EndDisabledGroup();
        if (ARToolKitAssetManager.OpticalCalibrations.Length <= 0)
        {
            EditorGUILayout.HelpBox("No optical calibration parameters found.", MessageType.Info);
        }
        if (arStaticCamera.Optical && ARToolKitAssetManager.OpticalCalibrations.Length <= 0)
        {
            ARController.Log("Error: ARStaticCamera - Attempted to enable optical see-through mode with no optical configurations in " + BasePath + ".");
            arStaticCamera.Optical = false;
        }

        if (!arStaticCamera.Optical)
        {
            // Reset to defaults in ARStaticCamera.cs
            arStaticCamera.EditorOpticalIndexL     = 0;
            arStaticCamera.EditorOpticalNameL      = null;
            arStaticCamera.OpticalParametersL      = null;
            arStaticCamera.EditorOpticalIndexR     = 0;
            arStaticCamera.EditorOpticalNameR      = null;
            arStaticCamera.OpticalParametersR      = null;
            arStaticCamera.OpticalEyeLateralOffset = 63.5f;
            return;
        }

        int newIndexL = EditorGUILayout.Popup("Left Eye Configuration", arStaticCamera.EditorOpticalIndexL, ARToolKitAssetManager.OpticalCalibrations);
        int newIndexR = EditorGUILayout.Popup("Right Eye Configuration", arStaticCamera.EditorOpticalIndexR, ARToolKitAssetManager.OpticalCalibrations);

        if ((string.CompareOrdinal(ARToolKitAssetManager.OpticalCalibrations[newIndexL], arStaticCamera.EditorOpticalNameL) != 0) ||
            (string.CompareOrdinal(ARToolKitAssetManager.OpticalCalibrations[newIndexR], arStaticCamera.EditorOpticalNameR) != 0))
        {
            arStaticCamera.EditorOpticalIndexL = newIndexL;
            arStaticCamera.EditorOpticalNameL  = ARToolKitAssetManager.OpticalCalibrations[newIndexL];
            arStaticCamera.OpticalParametersL  = ReadOpticalParamsByName(arStaticCamera.EditorOpticalNameL);
            arStaticCamera.EditorOpticalIndexR = newIndexR;
            arStaticCamera.EditorOpticalNameR  = ARToolKitAssetManager.OpticalCalibrations[newIndexR];
            arStaticCamera.OpticalParametersR  = ReadOpticalParamsByName(arStaticCamera.EditorOpticalNameR);
            arStaticCamera.Optical             = true;
        }


        if (newIndexL == newIndexR)
        {
            // Sane defaults derived from https://en.wikipedia.org/wiki/Interpupillary_distance
            arStaticCamera.OpticalEyeLateralOffset = EditorGUILayout.Slider("Inter-Pupular Distance (mm)", arStaticCamera.OpticalEyeLateralOffset, 0.50f, 0.80f);
            EditorGUILayout.HelpBox("If you are using the same optical configuration for both the left and right eyes, you must supply an IPD (inter-pupular" +
                                    "distance) value. This is the spacing from one pupil to the other, in milimeters.", MessageType.Warning);
        }

        EditorGUILayout.Separator();
        EditorGUILayout.HelpBox("Do not create a second camera object for the right eye! ARToolKit will do this for you.", MessageType.Info);
    }
示例#28
0
    // Load the native ARTrackable structure(s) and set the UID.
    public void Load()
    {
        lock (loadLock) {
            if (this.enabled == false)
            {
                return;
            }

            //ARController.Log(LogTag + "ARTrackable.Load()");
            if (UID != NO_ID)
            {
                return;
            }

            if (pluginFunctions == null || !pluginFunctions.IsInited())
            {
                // If arwInitialiseAR() has not yet been called, we can't load the native trackable yet.
                // ARController.InitialiseAR() will trigger this again when arwInitialiseAR() has been called.
                return;
            }

            // Work out the configuration string to pass to the native side.
            string dir = Application.streamingAssetsPath;
            string cfg = "";

            switch (Type)
            {
            case TrackableType.Square:
                // Multiply width by 1000 to convert from metres to artoolkitX's millimetres.
                cfg = "single_buffer;" + PatternWidth * 1000.0f + ";buffer=" + PatternContents;
                break;

            case TrackableType.SquareBarcode:
                // Multiply width by 1000 to convert from metres to artoolkitX's millimetres.
                cfg = "single_barcode;" + BarcodeID + ";" + PatternWidth * 1000.0f;
                break;

            case TrackableType.Multimarker:
                    #if !UNITY_METRO
                if (dir.Contains("://"))
                {
                    // On Android, we need to unpack the StreamingAssets from the .jar file in which
                    // they're archived into the native file system.
                    dir = Application.temporaryCachePath;
                    if (!unpackStreamingAssetToCacheDir(MultiConfigFile))
                    {
                        dir = "";
                    }
                    else
                    {
                        //string[] unpackFiles = getPatternFiles;
                        //foreach (string patternFile in patternFiles) {
                        //if (!unpackStreamingAssetToCacheDir(patternFile)) {
                        //    dir = "";
                        //    break;
                        //}
                    }
                }
                    #endif

                if (!string.IsNullOrEmpty(dir) && !string.IsNullOrEmpty(MultiConfigFile))
                {
                    cfg = "multi;" + System.IO.Path.Combine(dir, MultiConfigFile);
                }
                break;


            case TrackableType.NFT:
                    #if !UNITY_METRO
                if (dir.Contains("://"))
                {
                    // On Android, we need to unpack the StreamingAssets from the .jar file in which
                    // they're archived into the native file system.
                    dir = Application.temporaryCachePath;
                    foreach (string ext in NFTDataExts)
                    {
                        string basename = NFTDataName + "." + ext;
                        if (!unpackStreamingAssetToCacheDir(basename))
                        {
                            dir = "";
                            break;
                        }
                    }
                }
                    #endif

                if (!string.IsNullOrEmpty(dir) && !string.IsNullOrEmpty(NFTDataName))
                {
                    cfg = "nft;" + System.IO.Path.Combine(dir, NFTDataName);
                }
                break;

            case TrackableType.TwoD:
                #if !UNITY_METRO
                if (dir.Contains("://"))
                {
                    // On Android, we need to unpack the StreamingAssets from the .jar file in which
                    // they're archived into the native file system.
                    dir = Application.temporaryCachePath;
                    if (!unpackStreamingAssetToCacheDir(TwoDImageFile))
                    {
                        dir = "";
                    }
                }
                #endif

                if (!string.IsNullOrEmpty(dir) && !string.IsNullOrEmpty(TwoDImageFile))
                {
                    cfg = "2d;" + System.IO.Path.Combine(dir, TwoDImageFile) + ";" + TwoDImageWidth;
                }
                break;

            default:
                // Unknown marker type?
                break;
            }

            // If a valid config. could be assembled, get the native side to process it, and assign the resulting ARTrackable UID.
            if (!string.IsNullOrEmpty(cfg))
            {
                uid = pluginFunctions.arwAddTrackable(cfg);
                if (UID == NO_ID)
                {
                    ARController.Log(LogTag + "Error loading marker.");
                }
                else
                {
                    // Trackable loaded. Do any additional configuration.
                    //ARController.Log("Added marker with cfg='" + cfg + "'");

                    if (Type == TrackableType.Square || Type == TrackableType.SquareBarcode)
                    {
                        UseContPoseEstimation = currentUseContPoseEstimation;
                    }
                    Filtered         = currentFiltered;
                    FilterSampleRate = currentFilterSampleRate;
                    FilterCutoffFreq = currentFilterCutoffFreq;

                    // Retrieve any required information from the configured native ARTrackable.
                    if (Type == TrackableType.NFT || Type == TrackableType.TwoD)
                    {
                        if (Type == TrackableType.NFT)
                        {
                            NFTScale = currentNFTScale;
                        }

                        int imageSizeX, imageSizeY;
                        pluginFunctions.arwGetTrackablePatternConfig(UID, 0, null, out NFTWidth, out NFTHeight, out imageSizeX, out imageSizeY);
                        NFTWidth  *= 0.001f;
                        NFTHeight *= 0.001f;
                        //ARController.Log("Got NFTWidth=" + NFTWidth + ", NFTHeight=" + NFTHeight + ".");
                    }
                    else
                    {
                        // Create array of patterns. A single marker will have array length 1.
                        int numPatterns = pluginFunctions.arwGetTrackablePatternCount(UID);
                        //ARController.Log("Trackable with UID=" + UID + " has " + numPatterns + " patterns.");
                        if (numPatterns > 0)
                        {
                            patterns = new ARPattern[numPatterns];
                            for (int i = 0; i < numPatterns; i++)
                            {
                                patterns[i] = new ARPattern(pluginFunctions, UID, i);
                            }
                        }
                    }
                }
            }
        }
    }