private static void AddVirtualButton(ImageTargetBehaviour it, ConfigData.VirtualButton vb) { VirtualButtonBehaviour newVBBehaviour = it.CreateVirtualButton(vb.name, new Vector2(0.0f, 0.0f), new Vector2(1.0f, 1.0f)); newVBBehaviour.SetPosAndScaleFromButtonArea( new Vector2(vb.rectangle[0], vb.rectangle[1]), new Vector2(vb.rectangle[2], vb.rectangle[3])); VirtualButtonEditor.CreateVBMesh(newVBBehaviour); // Load default material. VirtualButtonEditor.CreateMaterial(newVBBehaviour); newVBBehaviour.enabled = vb.enabled; // Add Component to destroy VirtualButton meshes at runtime. newVBBehaviour.gameObject.AddComponent <TurnOffBehaviour>(); // Make sure Virtual Button is correctly aligned with Image Target newVBBehaviour.UpdatePose(); }
// This method creates a single data set from the trackables provided. // The method ignores the data set property in TrackableBehaviour and // adds all Trackables to a single file. // Default Trackables are not added to the data set. private ConfigData CreateDataSetFromTrackables(TrackableBehaviour[] trackables) { // Sanity check. if (trackables == null) { return(null); } ConfigData sceneData = new ConfigData(); foreach (TrackableBehaviour tb in trackables) { // Ignore non-data set trackables. if (!(tb is DataSetTrackableBehaviour)) { continue; } DataSetTrackableBehaviour trackable = (DataSetTrackableBehaviour)tb; string dataSetName = trackable.DataSetName; string trackableName = trackable.TrackableName; // We ignore default Trackables or undefined Trackables. if (dataSetName == QCARUtilities.GlobalVars.DEFAULT_DATA_SET_NAME || dataSetName == "" || trackableName == QCARUtilities.GlobalVars.DEFAULT_TRACKABLE_NAME || trackableName == "") { Debug.LogWarning("Ignoring default Trackable for export"); continue; } if (trackable.GetType() == typeof(ImageTargetBehaviour)) { ImageTargetBehaviour it = (ImageTargetBehaviour)trackable; ConfigData.ImageTarget itConfig = new ConfigData.ImageTarget(); itConfig.size = it.GetSize(); // Process Virtual Button list. VirtualButtonBehaviour[] vbs = it.GetComponentsInChildren <VirtualButtonBehaviour>(); itConfig.virtualButtons = new List <ConfigData.VirtualButton>(vbs.Length); foreach (VirtualButtonBehaviour vb in vbs) { Vector2 leftTop; Vector2 rightBottom; if (!vb.CalculateButtonArea(out leftTop, out rightBottom)) { // Invalid Button continue; } ConfigData.VirtualButton vbConfig = new ConfigData.VirtualButton(); vbConfig.name = vb.VirtualButtonName; vbConfig.enabled = vb.enabled; vbConfig.rectangle = new Vector4(leftTop.x, leftTop.y, rightBottom.x, rightBottom.y); vbConfig.sensitivity = vb.SensitivitySetting; itConfig.virtualButtons.Add(vbConfig); } sceneData.SetImageTarget(itConfig, it.TrackableName); } else if (trackable.GetType() == typeof(MultiTargetBehaviour)) { Debug.Log("Multi Targets not exported."); } } return(sceneData); }
// This method takes a configData object and creates a config.xml file at // the given path out of it. public bool fileToStruct(string configXMLPath, ConfigData configData) { if (!File.Exists(configXMLPath)) return false; using (XmlTextReader configReader = new XmlTextReader(configXMLPath)) { while (configReader.Read()) { if (configReader.NodeType == XmlNodeType.Element) { // "Global" Attributes string itNameAttr = ""; switch (configReader.Name) { case "ImageTarget": // Parse name from config file itNameAttr = configReader.GetAttribute("name"); if (itNameAttr == null) { Debug.LogWarning("Found ImageTarget without " + "name attribute in " + "config.xml. Image Target " + "will be ignored."); continue; } // Parse itSize from config file Vector2 itSize = Vector2.zero; string[] itSizeAttr = configReader.GetAttribute("size").Split(' '); if (itSizeAttr != null) { if (!QCARUtilities.SizeFromStringArray( out itSize, itSizeAttr)) { Debug.LogWarning("Found illegal itSize " + "attribute for Image " + "Target " + itNameAttr + " in config.xml. " + "Image Target will be " + "ignored."); continue; } } else { Debug.LogWarning("Image Target " + itNameAttr + " is missing a itSize " + "attribut in config.xml. " + "Image Target will be " + "ignored."); continue; } configReader.MoveToElement(); ConfigData.ImageTarget imageTarget = new ConfigData.ImageTarget(); imageTarget.size = itSize; imageTarget.virtualButtons = new List<ConfigData.VirtualButton>(); configData.SetImageTarget(imageTarget, itNameAttr); break; case "VirtualButton": // Parse name from config file string vbNameAttr = configReader.GetAttribute("name"); if (vbNameAttr == null) { Debug.LogWarning("Found VirtualButton " + "without name attribute in " + "config.xml. Virtual Button " + "will be ignored."); continue; } // Parse rectangle from config file Vector4 vbRectangle = Vector4.zero; string[] vbRectangleAttr = configReader.GetAttribute("rectangle").Split(' '); if (vbRectangleAttr != null) { if (!QCARUtilities.RectangleFromStringArray( out vbRectangle, vbRectangleAttr)) { Debug.LogWarning("Found invalid " + "rectangle attribute " + "for Virtual Button " + vbNameAttr + " in config.xml. " + "Virtual Button will " + "be ignored."); continue; } } else { Debug.LogWarning("Virtual Button " + vbNameAttr + " has no rectangle " + "attribute in config.xml. " + "Virtual Button will be " + "ignored."); continue; } // Parse enabled boolean from config file bool vbEnabled = true; string enabledAttr = configReader.GetAttribute("enabled"); if (enabledAttr != null) { if (string.Compare(enabledAttr, "true", true) == 0) { vbEnabled = true; } else if (string.Compare(enabledAttr, "false", true) == 0) { vbEnabled = false; } else { Debug.LogWarning("Found invalid enabled " + "attribute for Virtual " + "Button " + vbNameAttr + " in config.xml. " + "Default setting will " + "be used."); } } // Parse sensitivity from config file VirtualButtonBehaviour.Sensitivity vbSensitivity = VirtualButtonBehaviour.DEFAULT_SENSITIVITY; string vbSensitivityAttr = configReader.GetAttribute("sensitivity"); if (vbSensitivityAttr != null) { if (string.Compare(vbSensitivityAttr, "low", true) == 0) { vbSensitivity = VirtualButtonBehaviour.Sensitivity.LOW; } else if (string.Compare(vbSensitivityAttr, "medium", true) == 0) { vbSensitivity = VirtualButtonBehaviour.Sensitivity.MEDIUM; } else if (string.Compare(vbSensitivityAttr, "high", true) == 0) { vbSensitivity = VirtualButtonBehaviour.Sensitivity.HIGH; } else { Debug.LogWarning("Found illegal " + "sensitivity attribute " + "for Virtual Button " + vbNameAttr + " in config.xml. " + "Default setting will " + "be used."); } } configReader.MoveToElement(); ConfigData.VirtualButton virtualButton = new ConfigData.VirtualButton(); string latestITName = GetLatestITName(configData); virtualButton.name = vbNameAttr; virtualButton.rectangle = vbRectangle; virtualButton.enabled = vbEnabled; virtualButton.sensitivity = vbSensitivity; // Since the XML Reader runs top down we can assume // that the Virtual Button that has been found is // part of the latest Image Target. if (configData.ImageTargetExists(latestITName)) { configData.AddVirtualButton(virtualButton, latestITName); } else { Debug.LogWarning("Image Target with name " + latestITName + " could not be found. " + "Virtual Button " + vbNameAttr + "will not be added."); } break; case "MultiTarget": // Parse name from config file string mtNameAttr = configReader.GetAttribute("name"); if (mtNameAttr == null) { Debug.LogWarning("Found Multi Target without " + "name attribute in " + "config.xml. Multi Target " + "will be ignored."); continue; } configReader.MoveToElement(); ConfigData.MultiTarget multiTarget = new ConfigData.MultiTarget(); multiTarget.parts = new List<ConfigData.MultiTargetPart>(); configData.SetMultiTarget(multiTarget, mtNameAttr); break; case "Part": // Parse name from config file string prtNameAttr = configReader.GetAttribute("name"); if (prtNameAttr == null) { Debug.LogWarning("Found Multi Target Part " + "without name attribute in " + "config.xml. Part will be " + "ignored."); continue; } // Parse translations from config file Vector3 prtTranslation = Vector3.zero; string[] prtTranslationAttr = configReader.GetAttribute("translation").Split(' '); if (prtTranslationAttr != null) { if (!QCARUtilities.TransformFromStringArray( out prtTranslation, prtTranslationAttr)) { Debug.LogWarning("Found illegal " + "transform attribute " + "for Part " + prtNameAttr + " in config.xml. Part " + "will be ignored."); continue; } } else { Debug.LogWarning("Multi Target Part " + prtNameAttr + " has no " + "translation attribute in " + "config.xml. Part will be " + "ignored."); continue; } // Parse rotations from config file Quaternion prtRotation = Quaternion.identity; string[] prtRotationAttr = configReader.GetAttribute("rotation").Split(' '); if (prtRotationAttr != null) { if (!QCARUtilities.OrientationFromStringArray( out prtRotation, prtRotationAttr)) { Debug.LogWarning("Found illegal rotation " + "attribute for Part " + prtNameAttr + " in config.xml. Part " + "will be ignored."); continue; } } else { Debug.LogWarning("Multi Target Part " + prtNameAttr + " has no " + "rotation attribute in " + "config.xml. Part will be " + "ignored."); continue; } configReader.MoveToElement(); ConfigData.MultiTargetPart multiTargetPart = new ConfigData.MultiTargetPart(); string latestMTName = GetLatestMTName(configData); multiTargetPart.name = prtNameAttr; multiTargetPart.rotation = prtRotation; multiTargetPart.translation = prtTranslation; // Since the XML Reader runs top down we can assume // that the Virtual Button that has been found is // part of the latest Image Target. if (configData.MultiTargetExists(latestMTName)) { configData.AddMultiTargetPart(multiTargetPart, latestMTName); } else { Debug.LogWarning("Multi Target with name " + latestMTName + " could not be found. " + "Multi Target Part " + prtNameAttr + "will not be added."); } break; default: break; } } } } return true; }
// Update the config data buffer with new data. private void UpdateConfigData(TrackableBehaviour[] trackables) { // Sanity check. If no trackables have been set we return. if (trackables == null) { return; } // Lock config data buffer to make sure it is not changed while it is // updated with scene data. lock (mConfigData) { // We clear the frame markers from the config data if scene and // config.xml file synchronization is active. if (mSyncMarkersSceneAndConfig) { mConfigData.ClearFrameMarkers(); } foreach (TrackableBehaviour trackable in trackables) { string trackableName = trackable.TrackableName; // We ignore Trackables with default or empty names. if (trackableName == QCARUtilities.GlobalVars.DEFAULT_NAME || trackableName == "") { continue; } if (trackable.GetType() == typeof(ImageTargetBehaviour)) { ImageTargetBehaviour it = (ImageTargetBehaviour)trackable; ConfigData.ImageTarget itConfig; // If there is no image target with the requested name in the configuration we ignore the target. if (!SceneManager.Instance.GetImageTarget(it.TrackableName, out itConfig)) { continue; } itConfig.size = it.GetSize(); // Clear virtual buttons before processing. itConfig.virtualButtons.Clear(); // Process Virtual Button list. VirtualButtonBehaviour[] vbs = it.GetComponentsInChildren<VirtualButtonBehaviour>(); foreach (VirtualButtonBehaviour vb in vbs) { Vector2 leftTop; Vector2 rightBottom; if (!vb.CalculateButtonArea(out leftTop, out rightBottom)) { // Invalid Button continue; } ConfigData.VirtualButton vbConfig = new ConfigData.VirtualButton(); vbConfig.name = vb.VirtualButtonName; vbConfig.enabled = vb.enabled; vbConfig.rectangle = new Vector4(leftTop.x, leftTop.y, rightBottom.x, rightBottom.y); vbConfig.sensitivity = vb.SensitivitySetting; itConfig.virtualButtons.Add(vbConfig); } mConfigData.SetImageTarget(itConfig, it.TrackableName); } else if (trackable.GetType() == typeof(MarkerBehaviour)) { MarkerBehaviour fm = (MarkerBehaviour)trackable; ConfigData.FrameMarker fmConfig; SceneManager.Instance.GetFrameMarker(fm.MarkerID, out fmConfig); fmConfig.name = fm.TrackableName; fmConfig.size = fm.GetSize(); mConfigData.SetFrameMarker(fmConfig, fm.MarkerID); } } } }
// This method creates a single data set from the trackables provided. // The method ignores the data set property in TrackableBehaviour and // adds all Trackables to a single file. // Default Trackables are not added to the data set. private ConfigData CreateDataSetFromTrackables(TrackableBehaviour[] trackables) { // Sanity check. if (trackables == null) { return null; } ConfigData sceneData = new ConfigData(); foreach (TrackableBehaviour tb in trackables) { // Ignore non-data set trackables. if (!(tb is DataSetTrackableBehaviour)) { continue; } DataSetTrackableBehaviour trackable = (DataSetTrackableBehaviour)tb; string dataSetName = trackable.DataSetName; string trackableName = trackable.TrackableName; // We ignore default Trackables or undefined Trackables. if (dataSetName == QCARUtilities.GlobalVars.DEFAULT_DATA_SET_NAME || dataSetName == "" || trackableName == QCARUtilities.GlobalVars.DEFAULT_TRACKABLE_NAME || trackableName == "") { Debug.LogWarning("Ignoring default Trackable for export"); continue; } if (trackable.GetType() == typeof(ImageTargetBehaviour)) { ImageTargetBehaviour it = (ImageTargetBehaviour)trackable; ConfigData.ImageTarget itConfig = new ConfigData.ImageTarget(); itConfig.size = it.GetSize(); // Process Virtual Button list. VirtualButtonBehaviour[] vbs = it.GetComponentsInChildren<VirtualButtonBehaviour>(); itConfig.virtualButtons = new List<ConfigData.VirtualButton>(vbs.Length); foreach (VirtualButtonBehaviour vb in vbs) { Vector2 leftTop; Vector2 rightBottom; if (!vb.CalculateButtonArea(out leftTop, out rightBottom)) { // Invalid Button continue; } ConfigData.VirtualButton vbConfig = new ConfigData.VirtualButton(); vbConfig.name = vb.VirtualButtonName; vbConfig.enabled = vb.enabled; vbConfig.rectangle = new Vector4(leftTop.x, leftTop.y, rightBottom.x, rightBottom.y); vbConfig.sensitivity = vb.SensitivitySetting; itConfig.virtualButtons.Add(vbConfig); } sceneData.SetImageTarget(itConfig, it.TrackableName); } else if (trackable.GetType() == typeof(MultiTargetBehaviour)) { Debug.Log("Multi Targets not exported."); } } return sceneData; }
// This method takes a configData object and creates a config.xml file at // the given path out of it. public bool fileToStruct(string configXMLPath, ConfigData configData) { if (!File.Exists(configXMLPath)) { return(false); } using (XmlTextReader configReader = new XmlTextReader(configXMLPath)) { while (configReader.Read()) { if (configReader.NodeType == XmlNodeType.Element) { // "Global" Attributes string itNameAttr = ""; switch (configReader.Name) { case "ImageTarget": // Parse name from config file itNameAttr = configReader.GetAttribute("name"); if (itNameAttr == null) { Debug.LogWarning("Found ImageTarget without " + "name attribute in " + "config.xml. Image Target " + "will be ignored."); continue; } // Parse itSize from config file Vector2 itSize = Vector2.zero; string[] itSizeAttr = configReader.GetAttribute("size").Split(' '); if (itSizeAttr != null) { if (!QCARUtilities.SizeFromStringArray( out itSize, itSizeAttr)) { Debug.LogWarning("Found illegal itSize " + "attribute for Image " + "Target " + itNameAttr + " in config.xml. " + "Image Target will be " + "ignored."); continue; } } else { Debug.LogWarning("Image Target " + itNameAttr + " is missing a itSize " + "attribut in config.xml. " + "Image Target will be " + "ignored."); continue; } configReader.MoveToElement(); ConfigData.ImageTarget imageTarget = new ConfigData.ImageTarget(); imageTarget.size = itSize; imageTarget.virtualButtons = new List <ConfigData.VirtualButton>(); configData.SetImageTarget(imageTarget, itNameAttr); break; case "VirtualButton": // Parse name from config file string vbNameAttr = configReader.GetAttribute("name"); if (vbNameAttr == null) { Debug.LogWarning("Found VirtualButton " + "without name attribute in " + "config.xml. Virtual Button " + "will be ignored."); continue; } // Parse rectangle from config file Vector4 vbRectangle = Vector4.zero; string[] vbRectangleAttr = configReader.GetAttribute("rectangle").Split(' '); if (vbRectangleAttr != null) { if (!QCARUtilities.RectangleFromStringArray( out vbRectangle, vbRectangleAttr)) { Debug.LogWarning("Found invalid " + "rectangle attribute " + "for Virtual Button " + vbNameAttr + " in config.xml. " + "Virtual Button will " + "be ignored."); continue; } } else { Debug.LogWarning("Virtual Button " + vbNameAttr + " has no rectangle " + "attribute in config.xml. " + "Virtual Button will be " + "ignored."); continue; } // Parse enabled boolean from config file bool vbEnabled = true; string enabledAttr = configReader.GetAttribute("enabled"); if (enabledAttr != null) { if (string.Compare(enabledAttr, "true", true) == 0) { vbEnabled = true; } else if (string.Compare(enabledAttr, "false", true) == 0) { vbEnabled = false; } else { Debug.LogWarning("Found invalid enabled " + "attribute for Virtual " + "Button " + vbNameAttr + " in config.xml. " + "Default setting will " + "be used."); } } // Parse sensitivity from config file VirtualButtonBehaviour.Sensitivity vbSensitivity = VirtualButtonBehaviour.DEFAULT_SENSITIVITY; string vbSensitivityAttr = configReader.GetAttribute("sensitivity"); if (vbSensitivityAttr != null) { if (string.Compare(vbSensitivityAttr, "low", true) == 0) { vbSensitivity = VirtualButtonBehaviour.Sensitivity.LOW; } else if (string.Compare(vbSensitivityAttr, "medium", true) == 0) { vbSensitivity = VirtualButtonBehaviour.Sensitivity.MEDIUM; } else if (string.Compare(vbSensitivityAttr, "high", true) == 0) { vbSensitivity = VirtualButtonBehaviour.Sensitivity.HIGH; } else { Debug.LogWarning("Found illegal " + "sensitivity attribute " + "for Virtual Button " + vbNameAttr + " in config.xml. " + "Default setting will " + "be used."); } } configReader.MoveToElement(); ConfigData.VirtualButton virtualButton = new ConfigData.VirtualButton(); string latestITName = GetLatestITName(configData); virtualButton.name = vbNameAttr; virtualButton.rectangle = vbRectangle; virtualButton.enabled = vbEnabled; virtualButton.sensitivity = vbSensitivity; // Since the XML Reader runs top down we can assume // that the Virtual Button that has been found is // part of the latest Image Target. if (configData.ImageTargetExists(latestITName)) { configData.AddVirtualButton(virtualButton, latestITName); } else { Debug.LogWarning("Image Target with name " + latestITName + " could not be found. " + "Virtual Button " + vbNameAttr + "will not be added."); } break; case "MultiTarget": // Parse name from config file string mtNameAttr = configReader.GetAttribute("name"); if (mtNameAttr == null) { Debug.LogWarning("Found Multi Target without " + "name attribute in " + "config.xml. Multi Target " + "will be ignored."); continue; } configReader.MoveToElement(); ConfigData.MultiTarget multiTarget = new ConfigData.MultiTarget(); multiTarget.parts = new List <ConfigData.MultiTargetPart>(); configData.SetMultiTarget(multiTarget, mtNameAttr); break; case "Part": // Parse name from config file string prtNameAttr = configReader.GetAttribute("name"); if (prtNameAttr == null) { Debug.LogWarning("Found Multi Target Part " + "without name attribute in " + "config.xml. Part will be " + "ignored."); continue; } // Parse translations from config file Vector3 prtTranslation = Vector3.zero; string[] prtTranslationAttr = configReader.GetAttribute("translation").Split(' '); if (prtTranslationAttr != null) { if (!QCARUtilities.TransformFromStringArray( out prtTranslation, prtTranslationAttr)) { Debug.LogWarning("Found illegal " + "transform attribute " + "for Part " + prtNameAttr + " in config.xml. Part " + "will be ignored."); continue; } } else { Debug.LogWarning("Multi Target Part " + prtNameAttr + " has no " + "translation attribute in " + "config.xml. Part will be " + "ignored."); continue; } // Parse rotations from config file Quaternion prtRotation = Quaternion.identity; string[] prtRotationAttr = configReader.GetAttribute("rotation").Split(' '); if (prtRotationAttr != null) { if (!QCARUtilities.OrientationFromStringArray( out prtRotation, prtRotationAttr)) { Debug.LogWarning("Found illegal rotation " + "attribute for Part " + prtNameAttr + " in config.xml. Part " + "will be ignored."); continue; } } else { Debug.LogWarning("Multi Target Part " + prtNameAttr + " has no " + "rotation attribute in " + "config.xml. Part will be " + "ignored."); continue; } configReader.MoveToElement(); ConfigData.MultiTargetPart multiTargetPart = new ConfigData.MultiTargetPart(); string latestMTName = GetLatestMTName(configData); multiTargetPart.name = prtNameAttr; multiTargetPart.rotation = prtRotation; multiTargetPart.translation = prtTranslation; // Since the XML Reader runs top down we can assume // that the Virtual Button that has been found is // part of the latest Image Target. if (configData.MultiTargetExists(latestMTName)) { configData.AddMultiTargetPart(multiTargetPart, latestMTName); } else { Debug.LogWarning("Multi Target with name " + latestMTName + " could not be found. " + "Multi Target Part " + prtNameAttr + "will not be added."); } break; default: break; } } } } return(true); }