/// <summary> /// Remove a specific word behaviour from list and optionally destroy game object. /// This might also remove a template, i.e. no further trackables will be augmented for a specific word or for a template /// </summary> public override void DestroyWordBehaviour(WordBehaviour behaviour, bool destroyGameObject = true) { var keys = mWordBehaviours.Keys.ToArray(); foreach (var key in keys) { if (mWordBehaviours[key].Contains(behaviour)) { mWordBehaviours[key].Remove(behaviour); // no behaviours left - delete whole list if (mWordBehaviours[key].Count == 0) { mWordBehaviours.Remove(key); } if (destroyGameObject) { Object.Destroy(behaviour.gameObject); mWordBehavioursMarkedForDeletion.Add(behaviour); } else { IEditorWordBehaviour editorTrackableBehaviour = behaviour; editorTrackableBehaviour.UnregisterTrackable(); } } } }
/// <summary> /// Remove a specific word behaviour from list and optionally destroy game object. /// This might also remove a template, i.e. no further trackables will be augmented for a specific word or for a template /// </summary> public override void DestroyWordBehaviour(WordBehaviour behaviour, bool destroyGameObject = true) { var keys = mWordBehaviours.Keys.ToArray(); foreach (var key in keys) { if (mWordBehaviours[key].Contains(behaviour)) { mWordBehaviours[key].Remove(behaviour); // no behaviours left - delete whole list if (mWordBehaviours[key].Count == 0) mWordBehaviours.Remove(key); if (destroyGameObject) { Object.Destroy(behaviour.gameObject); mWordBehavioursMarkedForDeletion.Add(behaviour); } else { IEditorWordBehaviour editorTrackableBehaviour = behaviour; editorTrackableBehaviour.UnregisterTrackable(); } } } }
private WordBehaviour AssociateWordBehaviour(WordResult wordResult, WordBehaviour wordBehaviourTemplate) { if (mActiveWordBehaviours.Count >= mMaxInstances) { return(null); } var word = wordResult.Word; var wordBehaviour = wordBehaviourTemplate; var ewb = (IEditorWordBehaviour)wordBehaviour; ewb.SetNameForTrackable(word.StringValue); ewb.InitializeWord(word); mActiveWordBehaviours.Add(word.ID, wordBehaviour); return(wordBehaviour); }
/// <summary> /// Associate multiple words with word behaviours. This function prefers word results that are already in the waiting queue over new words. /// </summary> private void AssociateWordResultsWithBehaviours() { //first handle all items in the waiting queue (has to be copied because it will be changed) //new values will be added to the waiting queue inside AssociateWordBehaviour var waitingQueue = new List <Word>(mWaitingQueue); foreach (var word in waitingQueue) { if (mTrackedWords.ContainsKey(word.ID)) { var wr = mTrackedWords[word.ID]; //the word can be removed from the waiting list because it has been associated with a behaviour if (AssociateWordBehaviour(wr) != null) { mWaitingQueue.Remove(word); } } else { //word is not tracked anymore mWaitingQueue.Remove(word); } } //handle new word results that are currently tracked foreach (WordResult wordResult in mNewWords) { WordBehaviour wordBehaviour = AssociateWordBehaviour(wordResult); //no corresponding word prefab was found. put tracked word result to waiting list if (wordBehaviour == null) { mWaitingQueue.Add(wordResult.Word); } } }
/// <summary> /// Creates a text-mesh and a rectangular mesh. The size of the rectangle depends on the size of the text. /// </summary> private static void UpdateMesh(WordBehaviour behaviour) { var gameObject = behaviour.gameObject; var editorBehaviour = (IEditorWordBehaviour) behaviour; //get existing child-object with name "Text" or create new one GameObject childGameObject; var child = gameObject.transform.FindChild("Text"); if (!child) { childGameObject = new GameObject("Text"); childGameObject.transform.parent = gameObject.transform; } else { childGameObject = child.gameObject; } childGameObject.transform.localScale = Vector3.one; childGameObject.transform.localRotation = Quaternion.AngleAxis(90.0f, Vector3.right); childGameObject.transform.localPosition = Vector3.zero; //disable editor-functionality including the transform-handles in the 3d editor //childGameObject.hideFlags = HideFlags.NotEditable; //get or create text-mesh var textMesh = childGameObject.GetComponent<TextMesh>(); if (!textMesh) textMesh = childGameObject.AddComponent<TextMesh>(); //load default font from resources var fontPath = QCARUtilities.GlobalVars.FONT_PATH; var font = (Font)AssetDatabase.LoadAssetAtPath(fontPath + "SourceSansPro.ttf", typeof(Font)); if (font != null) { textMesh.fontSize = 0; textMesh.font = font; } else { //fallback when font is not available: use built-in font from unity, won't work on Android and Unity 3.5 Debug.LogWarning("Standard font for Word-prefabs were not found. You might not be able to use it during runtime."); textMesh.font = Resources.Load("Arial", typeof(Font)) as Font; textMesh.fontSize = 36; } //get or create renderer and assign material for rendering texture and set font color to black var renderer = childGameObject.GetComponent<MeshRenderer>(); if (!renderer) renderer = childGameObject.AddComponent<MeshRenderer>(); //copy font-material to get persistent color and shader var material = new Material(textMesh.font.material); material.color = Color.black; material.shader = Shader.Find("Custom/Text3D"); renderer.sharedMaterial = material; //define text for mesh textMesh.text = editorBehaviour.IsTemplateMode ? "\"AnyWord\"" : editorBehaviour.SpecificWord; //textMesh.transform.hideFlags = HideFlags.NotEditable; //set transformation to identity for computing correct axis-aligned bounding box var tempRotation = gameObject.transform.localRotation; var tempScale = gameObject.transform.localScale; var tempPosition = gameObject.transform.localPosition; gameObject.transform.localRotation = Quaternion.identity; gameObject.transform.localScale = Vector3.one; gameObject.transform.localPosition = Vector3.zero; //compute axis-aligned bounding box for resizing rectangle var bounds = GetBoundsForAxisAlignedTextMesh(textMesh); UpdateRectangleMesh(gameObject, bounds); UpdateRectangleMaterial(gameObject); //set transformation to original value gameObject.transform.localRotation = tempRotation; gameObject.transform.localScale = tempScale; gameObject.transform.localPosition = tempPosition; }
/// <summary> /// Get the word behaviour that is associated with a currently tracked word /// </summary> /// <param name="word">trackable</param> /// <param name="behaviour">resulting word behaviour, might be null if specified word is not associated to a behaviour</param> /// <returns>returns true if word behaviour exists for specified word trackable</returns> public abstract bool TryGetWordBehaviour(Word word, out WordBehaviour behaviour);
/// <summary> /// Remove a specific word behaviour from list and optionally destroy game object. /// This might also remove a template, i.e. no further trackables will be augmented for a specific word or for a template /// </summary> public abstract void DestroyWordBehaviour(WordBehaviour behaviour, bool destroyGameObject = true);
private WordBehaviour AssociateWordBehaviour(WordResult wordResult, WordBehaviour wordBehaviourTemplate) { if (mActiveWordBehaviours.Count >= mMaxInstances) return null; var word = wordResult.Word; var wordBehaviour = wordBehaviourTemplate; var ewb = (IEditorWordBehaviour) wordBehaviour; ewb.SetNameForTrackable(word.StringValue); ewb.InitializeWord(word); mActiveWordBehaviours.Add(word.ID, wordBehaviour); return wordBehaviour; }
/// <summary> /// create a new instance of the input word behaviour /// </summary> private static WordBehaviour InstantiateWordBehaviour(WordBehaviour input) { var go = Object.Instantiate(input.gameObject) as GameObject; return go.GetComponent<WordBehaviour>(); }
/// <summary> /// Get the word behaviour that is associated with a currently tracked word /// </summary> /// <param name="word">trackable</param> /// <param name="behaviour">resulting word behaviour, might be null if specified word is not associated to a behaviour</param> /// <returns>returns true if word behaviour exists for specified word trackable</returns> public override bool TryGetWordBehaviour(Word word, out WordBehaviour behaviour) { return mActiveWordBehaviours.TryGetValue(word.ID, out behaviour); }
/// <summary> /// Remove a specific word behaviour from list and optionally destroy game object. /// This might also remove a template, i.e. no further trackables will be augmented for a specific word or for a template /// </summary> public abstract void DestroyWordBehaviour(WordBehaviour behaviour, bool destroyGameObject = true);
/// <summary> /// Get the word behaviour that is associated with a currently tracked word /// </summary> /// <param name="word">trackable</param> /// <param name="behaviour">resulting word behaviour, might be null if specified word is not associated to a behaviour</param> /// <returns>returns true if word behaviour exists for specified word trackable</returns> public abstract bool TryGetWordBehaviour(Word word, out WordBehaviour behaviour);
/// <summary> /// Get the word behaviour that is associated with a currently tracked word /// </summary> /// <param name="word">trackable</param> /// <param name="behaviour">resulting word behaviour, might be null if specified word is not associated to a behaviour</param> /// <returns>returns true if word behaviour exists for specified word trackable</returns> public override bool TryGetWordBehaviour(Word word, out WordBehaviour behaviour) { return(mActiveWordBehaviours.TryGetValue(word.ID, out behaviour)); }
/// <summary> /// create a new instance of the input word behaviour /// </summary> private static WordBehaviour InstantiateWordBehaviour(WordBehaviour input) { var go = Object.Instantiate(input.gameObject) as GameObject; return(go.GetComponent <WordBehaviour>()); }
/// <summary> /// Creates a text-mesh and a rectangular mesh. The size of the rectangle depends on the size of the text. /// </summary> private static void UpdateMesh(WordBehaviour behaviour) { var gameObject = behaviour.gameObject; var editorBehaviour = (IEditorWordBehaviour)behaviour; //get existing child-object with name "Text" or create new one GameObject childGameObject; var child = gameObject.transform.FindChild("Text"); if (!child) { childGameObject = new GameObject("Text"); childGameObject.transform.parent = gameObject.transform; } else { childGameObject = child.gameObject; } childGameObject.transform.localScale = Vector3.one; childGameObject.transform.localRotation = Quaternion.AngleAxis(90.0f, Vector3.right); childGameObject.transform.localPosition = Vector3.zero; //disable editor-functionality including the transform-handles in the 3d editor //childGameObject.hideFlags = HideFlags.NotEditable; //get or create text-mesh var textMesh = childGameObject.GetComponent <TextMesh>(); if (!textMesh) { textMesh = childGameObject.AddComponent <TextMesh>(); } //load default font from resources var fontPath = QCARUtilities.GlobalVars.FONT_PATH; var font = (Font)AssetDatabase.LoadAssetAtPath(fontPath + "SourceSansPro.ttf", typeof(Font)); if (font != null) { textMesh.fontSize = 0; textMesh.font = font; } else { //fallback when font is not available: use built-in font from unity, won't work on Android and Unity 3.5 Debug.LogWarning("Standard font for Word-prefabs were not found. You might not be able to use it during runtime."); textMesh.font = Resources.Load("Arial", typeof(Font)) as Font; textMesh.fontSize = 36; } //get or create renderer and assign material for rendering texture and set font color to black var renderer = childGameObject.GetComponent <MeshRenderer>(); if (!renderer) { renderer = childGameObject.AddComponent <MeshRenderer>(); } //copy font-material to get persistent color and shader var material = new Material(textMesh.font.material); material.color = Color.black; material.shader = Shader.Find("Custom/Text3D"); renderer.sharedMaterial = material; //define text for mesh textMesh.text = editorBehaviour.IsTemplateMode ? "\"AnyWord\"" : editorBehaviour.SpecificWord; //textMesh.transform.hideFlags = HideFlags.NotEditable; //set transformation to identity for computing correct axis-aligned bounding box var tempRotation = gameObject.transform.localRotation; var tempScale = gameObject.transform.localScale; var tempPosition = gameObject.transform.localPosition; gameObject.transform.localRotation = Quaternion.identity; gameObject.transform.localScale = Vector3.one; gameObject.transform.localPosition = Vector3.zero; //compute axis-aligned bounding box for resizing rectangle var bounds = GetBoundsForAxisAlignedTextMesh(textMesh); UpdateRectangleMesh(gameObject, bounds); UpdateRectangleMaterial(gameObject); //set transformation to original value gameObject.transform.localRotation = tempRotation; gameObject.transform.localScale = tempScale; gameObject.transform.localPosition = tempPosition; }