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>"); } }
// 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)); } }
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); }
/// <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(); } }
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))); }
private void Awake() { if (null == instance) { instance = this; } else { ARController.Log("ERROR: MORE THAN ONE ARSTATICCAMERA IN SCENE!"); } }
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 }
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 } }
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."); } }
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."); } }
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); }
// 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); } } }
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); }
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(); } }
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 }); } } } } }
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); } } }
/// <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."); } }
// 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); } } } } } }
// 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); } } } } }
public void DisplayCameraPermissionsRationale() { ARController.Log("Displaying camera permissions rationale view."); //TODO: implement view }
/// <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."); }
// 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"); } }
// 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); }
// 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); } } } } } } }