Скрипт, определяющий поведение VirtualButton - Разработка системы дополненной реальности с поддержкой распознавания жестов в режиме реального времени
/*==============================================================================Copyright (c) 2010-2013 QUALCOMM Austria Research Center GmbH. All Rights Reserved. Qualcomm Confidential and Proprietary==============================================================================*/
Using System;
Using System. Collections. Generic;
Using System. Runtime. InteropServices;
Using UnityEngine;
/// <summary>
///Этот скрипт связывает VirtualButton с виртуальным объектом
///
/// </summary>
Public class VirtualButtonBehaviour: MonoBehaviour, IEditorVirtualButtonBehaviour
{
#region PROPERTIES
/// <summary>
/// Имя виртуальной кнопки.
/// </summary>
Public string VirtualButtonName
{
Get { return mName; }
}
/// <summary>
/// Возвращает True если кнопка нажата.
/// </summary>
Public bool Pressed
{ get { return mPressed; }
}
/// <summary>
/// если позиция была обновленна
/// </summary>
Public bool HasUpdatedPose
{
Get { return mHasUpdatedPose; }
}
Public bool UnregisterOnDestroy
{
Get
{
Return mUnregisterOnDestroy;
}
Set
{
MUnregisterOnDestroy = value;
}
}
/// <summary>
/// Создание VirtualButton Object во время выполнения
/// </summary>
Public VirtualButton VirtualButton
{
Get { return mVirtualButton; }
}
#endregion // PROPERTIES
#region CONSTANTS
/// <summary>
/// Вертикальная составляющая внешнего вида кнопки
/// </summary>
Public const float TARGET_OFFSET = 0.001f;
#endregion // CONSTANTS
#region PRIVATE_MEMBER_VARIABLES
[SerializeField]
[HideInInspector]
Private string mName;
[SerializeField]
[HideInInspector]
Private VirtualButton. Sensitivity mSensitivity;
[SerializeField]
[HideInInspector]
Private bool mHasUpdatedPose = false;
[SerializeField]
[HideInInspector]
Private Matrix4x4 mPrevTransform = Matrix4x4.zero;
[SerializeField]
[HideInInspector]
Private GameObject mPrevParent = null;
Private bool mSensitivityDirty;
Private bool mPreviouslyEnabled;
Private bool mPressed;
Private List<IVirtualButtonEventHandler> mHandlers = null;
Private Vector2 mLeftTop;
Private Vector2 mRightBottom;
Private bool mUnregisterOnDestroy;
VirtualButton mVirtualButton;
#endregion // PRIVATE_MEMBER_VARIABLES
#region CONSTRUCTION
Public VirtualButtonBehaviour()
{
MName = "";
MPressed = false;
MSensitivity = VirtualButton. DEFAULT_SENSITIVITY;
MSensitivityDirty = false;
MHandlers = new List<IVirtualButtonEventHandler>();
MHasUpdatedPose = false;
}
#endregion // CONSTRUCTION
#region PUBLIC_METHODS
/// <summary>
/// Registers an event handler with this Virtual Button which will be called
/// when a state changed is detected.
/// </summary>
Public void RegisterEventHandler(IVirtualButtonEventHandler eventHandler)
{
MHandlers. Add(eventHandler);
}
/// <summary>
/// Registers an event handler with this Virtual Button which will be called
/// when a state changed is detected.
/// Returns true on success. False otherwise.
/// </summary>
Public bool UnregisterEventHandler(IVirtualButtonEventHandler eventHandler)
{
Return mHandlers. Remove(eventHandler);
}
/// <summary>
/// Calculates the 2D button area that the Virtual Button currently occupies
/// in the Image Target.
/// Returns true if the area was computed successfully. False otherwise.
/// Passes out the top left and bottom right position of the rectangle area.
/// </summary>
Public bool CalculateButtonArea(out Vector2 topLeft,
Out Vector2 bottomRight)
{
// Error if we don't have an image target as a root:
ImageTargetBehaviour itb = this. GetImageTargetBehaviour();
If (itb == null)
{
TopLeft = bottomRight = Vector2.zero;
Return false;
}
Vector3 vbPosITSpace = itb. transform. InverseTransformPoint(
This. transform. position);
// The scale of the image Target:
Float itScale = itb. transform. lossyScale[0];
// Scale the button position:
Vector2 pos = new Vector2(vbPosITSpace[0] * itScale,
VbPosITSpace[2] * itScale);
// Scale the button area:
Vector2 scale = new Vector2(this. transform. lossyScale[0],
This. transform. lossyScale[2]);
// Calculate top left and bottom right points:
Vector2 radius = Vector2.Scale(scale * 0.5F, new Vector2(1.0f, -1.0f));
TopLeft = pos - radius;
BottomRight = pos + radius;
// Done:
Return true;
}
/// <summary>
/// Update the virtual button rect in native
/// </summary>
Public bool UpdateAreaRectangle()
{
VirtualButton. RectangleData rectData = new VirtualButton. RectangleData();
RectData. leftTopX = mLeftTop. x;
RectData. leftTopY = mLeftTop. y;
RectData. rightBottomX = mRightBottom. x;
RectData. rightBottomY = mRightBottom. y;
If (mVirtualButton == null) return false;
Return mVirtualButton. SetArea(rectData);
}
/// <summary>
/// Update sensitivity in native
/// </summary>
Public bool UpdateSensitivity()
{
If (mVirtualButton == null) return false;
Return mVirtualButton. SetSensitivity(mSensitivity);
}
/// <summary>
/// Update enabled status in native
/// </summary>
Private bool UpdateEnabled()
{
Return mVirtualButton. SetEnabled(enabled);
}
/// <summary>
/// UpdatePose() is called each frame to ensure the virtual button is clamped
/// to the image target plane and remains axis-aligned with respect to the
/// target. Return true if the defining area of the virtual button has
/// changed, false otherwise.
/// </summary>
Public bool UpdatePose()
{
// The image target to which the button belongs:
ImageTargetBehaviour itb = this. GetImageTargetBehaviour();
// If there is no image target we return:
If (itb == null)
{
Return false;
}
// We explicitly disallow any objects with non-uniform scaling in the
// object hierachy of the virtual button. Combined with a rotation
// this would result in skewing the virtual button.
Transform t = transform. parent;
While (t!= null)
{
If (t. localScale[0] != t. localScale[1] ||
T. localScale[0] != t. localScale[2])
{
Debug. LogWarning("Detected non-uniform scale in virtual " +
" button object hierarchy. Forcing uniform scaling of " +
"object '" + t. name + "'.");
// Force uniform scale:
T. localScale = new Vector3(t. localScale[0], t. localScale[0],
T. localScale[0]);
}
T = t. parent;
}
// Remember we have updated once:
MHasUpdatedPose = true;
// Clamp to center of parent object:
If (transform. parent!= null &;&;
Transform. parent. gameObject!= itb. gameObject)
{
Transform. localPosition = Vector3.zero;
}
// Clamp position to image target plane:
Vector3 vbPosITSpace = itb. transform. InverseTransformPoint(
This. transform. position);
// Set the y offset in Image Target space:
VbPosITSpace. y = TARGET_OFFSET;
Vector3 vbPosWorldSpace = itb. transform. TransformPoint(vbPosITSpace);
This. transform. position = vbPosWorldSpace;
// Clamp orientation to the image target plane:
This. transform. rotation = itb. transform. rotation;
// Update the button area:
Vector2 leftTop, rightBottom;
CalculateButtonArea(out leftTop, out rightBottom);
// Change the button area only if the change is larger than a fixed
// proportion of the image target size:
Float threshold = itb. transform. localScale[0] * 0.001f;
If (!Equals(leftTop, mLeftTop, threshold) ||
!Equals(rightBottom, mRightBottom, threshold))
{
// Area has changed significantly:
MLeftTop = leftTop;
MRightBottom = rightBottom;
Return true;
}
// Area has not changed significantly:
Return false;
}
/// <summary>
/// Called after the QCARBehaviour has updated.
/// </summary>
Public void OnTrackerUpdated(bool pressed)
{
If (mPreviouslyEnabled!= enabled)
{
MPreviouslyEnabled = enabled;
UpdateEnabled();
}
If (!enabled)
{
Return;
}
// Trigger the appropriate callback if there was state change:
If (mPressed!= pressed &;&; mHandlers!= null)
{
If (pressed)
{
Foreach (IVirtualButtonEventHandler handler in mHandlers)
{
Handler. OnButtonPressed(this);
}
}
Else
{
Foreach (IVirtualButtonEventHandler handler in mHandlers)
{
Handler. OnButtonReleased(this);
}
}
}
// Cache pressed state:
MPressed = pressed;
}
/// <summary>
/// Returns the Image Target that this Virtual Button is associated with.
/// </summary>
Public ImageTargetBehaviour GetImageTargetBehaviour()
{
If (transform. parent == null)
Return null;
GameObject p = transform. parent. gameObject;
While (p!= null)
{
ImageTargetBehaviour itb = p. GetComponent<ImageTargetBehaviour>();
If (itb!= null)
{
Return itb;
}
If (p. transform. parent == null)
{
// Not found:
Return null;
}
P = p. transform. parent. gameObject;
}
// Not found:
Return null;
}
#endregion // PUBLIC_METHODS
#region EDITOR_INTERFACE_IMPLEMENTATION
// Initializes the Virtual Button name. Not allowed after runtime object has been created.
Bool IEditorVirtualButtonBehaviour. SetVirtualButtonName(string virtualButtonName)
{
If (mVirtualButton == null)
{
MName = virtualButtonName;
Return true;
}
Return false;
}
VirtualButton. Sensitivity IEditorVirtualButtonBehaviour. SensitivitySetting
{
Get { return mSensitivity; }
}
// sets the sensitivity. At runtime the VirtualButton object should be used to change sensibility.
Bool IEditorVirtualButtonBehaviour. SetSensitivitySetting(VirtualButton. Sensitivity sensibility)
{
If (mVirtualButton == null)
{
MSensitivity = sensibility;
MSensitivityDirty = true;
Return true;
}
Return false;
}
Matrix4x4 IEditorVirtualButtonBehaviour. PreviousTransform
{
Get { return mPrevTransform; }
}
Bool IEditorVirtualButtonBehaviour. SetPreviousTransform(Matrix4x4 transform)
If (mVirtualButton == null)
{
MPrevTransform = transform;
Return true;
}
Return false;
}
GameObject IEditorVirtualButtonBehaviour. PreviousParent
{
Get { return mPrevParent; }
}
Bool IEditorVirtualButtonBehaviour. SetPreviousParent(GameObject parent)
{
If (mVirtualButton == null)
{
MPrevParent = parent;
Return true;
}
Return false;
}
// Initializes the Virtual Button runtime object void IEditorVirtualButtonBehaviour. InitializeVirtualButton(VirtualButton virtualButton)
{
MVirtualButton = virtualButton;
}
// Sets position and scale in the transform component of the Virtual Button
// game object. The values are calculated from rectangle values (top-left
// and bottom-right corners).
// Returns false if Virtual Button is not child of an Image Target.
Bool IEditorVirtualButtonBehaviour. SetPosAndScaleFromButtonArea(Vector2 topLeft, Vector2 bottomRight)
{
// Error if we don't have an image target as a root:
ImageTargetBehaviour itb = this. GetImageTargetBehaviour();
If (itb == null)
{
Return false;
}
Float itScale = itb. transform. lossyScale[0];
Vector2 pos = (topLeft + bottomRight) * 0.5f;
Vector2 scale = new Vector2(bottomRight[0] - topLeft[0],
TopLeft[1] - bottomRight[1]);
Vector3 vbPosITSpace =
New Vector3(pos[0] / itScale, VirtualButtonBehaviour. TARGET_OFFSET, pos[1] / itScale);
Vector3 vbScaleITSpace =
New Vector3(scale[0],
(scale[0] + scale[1]) * 0.5f,
Scale[1]);
This. transform. position = itb. transform. TransformPoint(vbPosITSpace);
// Image Target scale is canceled out (included in both scales)
This. transform. localScale =
VbScaleITSpace / this. transform. parent. lossyScale[0];
// Done:
Return true;
}
#endregion // EDITOR_INTERFACE_IMPLEMENTATION
#region UNITY_MONOBEHAVIOUR_METHODS
// Overriding standard Unity MonoBehaviour methods.
Void LateUpdate()
{
// Update the button pose:
If (UpdatePose())
{
// Area has changed, update the QCAR trackable:
UpdateAreaRectangle();
}
// Update the sensitivity of the button if it has changed since the
// last update:
If (mSensitivityDirty)
{
If (UpdateSensitivity())
{
MSensitivityDirty = false;
}
}
}
Void OnDisable()
{
If (QCARRuntimeUtilities. IsQCAREnabled())
{
If (mPreviouslyEnabled!= enabled)
{
MPreviouslyEnabled = enabled;
UpdateEnabled();
}
// Trigger the appropriate callback if there was state change:
If (mPressed &;&; mHandlers!= null)
{
Foreach (IVirtualButtonEventHandler handler in mHandlers)
{
Handler. OnButtonReleased(this);
}
}
// Cache pressed state:
MPressed = false;
}
}
Void OnDestroy()
{
If (Application. isPlaying)
{
If (mUnregisterOnDestroy)
{
ImageTargetBehaviour itb = GetImageTargetBehaviour();
If (itb!= null)
Itb. ImageTarget. DestroyVirtualButton(mVirtualButton);
}
}
}
#endregion // UNITY_MONOBEHAVIOUR_METHODS
#region PRIVATE_METHODS
Private static bool Equals(Vector2 vec1, Vector2 vec2, float threshold)
{
Vector2 diff = vec1 - vec2;
Return (Math. Abs(diff. x) < threshold) &;&; (Math. Abs(diff. y) < threshold);
}
#endregion // PRIVATE_METHODS
}
Похожие статьи
-
1) Создание маркера Для создания маркера дополненной реальности в составе Vuforia SDK имеется специальный Target Manager (рисунок 16), который...
-
Определение дополненной реальности Термин дополненной реальности (augmented reality, AR) предположительно был предложен работавшим на корпорацию Boeing...
-
Основными устройствами, используемым в системах дополненной реальности являются дисплеи, устройства ввода, устройства отслеживания и компьютер. Дисплеи...
-
Человек получает представление об окружающем пространстве с помощью большого набора органов чувств. Система дополненной реальности, являясь посредником...
-
Мультимодальные интерфейсы объединяют реальные формы устройств ввода с натуральными формами языка и поведения, такими как речь, осязание, жесты рукой или...
-
Совместные AR интерфейсы включают в себя использование нескольких дисплеев для поддержки удаленной совместной деятельности. Для создания совместной...
-
Один из наиболее важных аспектов при создании систем дополненной реальности - это создать соответствующий интуитивно понятный интерфейс между...
-
Есть много типов устройств ввода для AR систем. Некоторые системы используют перчатки. Другие, такие как ReachMedia [13] используют беспроводные...
-
Общая характеристика Для оценки общей возможности распознавания жестов в мобильных АR, сравним стандартные взаимодействия, через сенсорный экран, и тип...
-
Мобильные приложения дополненной реальности чаще всего являются развлекательными, образовательными, навигационными или информационные. Например...
-
Существует достаточно широкий спектр областей науки и техники, в которых может применяться дополненная реальность. Однако в первую очередь можно выделить...
-
Развлекательная и образовательная область включает в себя "культурные" приложения для осмотра достопримечательностей и музейные путеводители, игровые...
-
Хотя существует множество инновационных способов использования дополненной реальности, можно выделить четыре типа приложений, в которых чаще всего...
-
Хорошо известно, что для качественных AR систем, чтобы предоставить реалистичный результат требуется очень точно отслеживать реальную среду для...
-
Многие исследовательские группы поднимали проблему социально приемлемых технологий. Мобильные системы, постоянно сталкиваются с проблемой социального...
-
В виду популяризации мобильных устройств разного формата (мобильные телефоны, планшеты, электронные книги), необходимо рассмотреть потенциальные угрозы...
-
В рамках выполнения дипломной работы был проведен обзор технологий дополненной реальности, рассмотрены и проанализированы возможные типы взаимодействия...
-
Общие положения Охрана труда - это система законодательных актов, социально-экономических, организационных, технических, гигиенических и...
-
Работа, предусмотренная выполнением производственного заказа, носит инженерный характер и предусматривает работу пользователя с разнообразным программным...
-
Надежность - свойство объекта сохранять во времени в установленных пределах значения всех параметров, характеризующих способность выполнять требуемые...
-
Мобильные системы дополненной реальности включают в себя мобильные приложения для телефонов. Мобильные AR подразумевают использование различных мобильных...
-
Прототип системы разрабатывался для мобильных устройств под управление операционной системы iOS. Для разработки использовался Фреймворк Vuforia SDK и...
-
Таблица 2. Таблица альтернатив и критериев Критерии альтернативы Кроссплатформенность Наличие документации и литературы Поддержка различных языков...
-
Выбор Фреймворка для разработки системы Перед началом разработки необходимо произвести выбор Фреймворка (набора библиотек). Обзор альтернатив OpenCV -...
-
Для того чтобы далее исследовать потенциал использования жестов для систем дополненной реальности, рассмотрим манипуляции виртуальными объектами,...
-
Второй вид взаимодействия использует положения и ориентации устройства (определяется с помощь данных, полученных со встроенного акселерометра и компаса)...
-
Рассмотри несколько видов взаимодействия, которые могли бы решить поставленную задачу. Для простоты рассмотрим взаимодействие с виртуальным объектом...
-
В мобильной дополненной реальности (AR), пользователи смотрят на прямое изображение, полученное с видеокамеры на их мобильном устройстве и сцены, которые...
-
А - Разработка программы на языке C++, реализующей игру "Морской бой"
ТЕКСТ ПРОГРАММЫ Текст программы состоит из следующих модулей: UShipBattle. h, UShipBattle. cpp, ShipBattle. cpp ShipBattle. cpp // - #include <vcl. h>...
-
Постановка задачи - Написание игры на Java
Требуется создать игру, в которой пользователь для победы должен найти спрятанный на карте объект. Построение алгоритма задачи. Приложение имеет меню...
-
Цель Работы - изучить одну из базовых концепций ООП, наследование классов в С++, заключающуюся в построении цепочек классов, связанных иерархически,...
-
Для участков контура, которые задаются линейной функцией, используем метод линейной интерполяции по ЦДА. А для участков, которые описываются функцией для...
-
В - Разработка программы на языке C++, реализующей игру "Морской бой"
ИСХОДНЫЙ КОД ЛИСТИНГА В данной программе четко прослеживаются группы функций, которые из-за выполняемых ними операций стоит объединить в классы....
-
- Статические ЭС разрабатываются в предметных областях, в которых база знаний и интерпретируемые данные не меняются во времени. Они стабильны. Пример:...
-
Необходимо отметить специальный класс приложений - систем поддержки принятия решений, позволяющие моделировать правила и стратегии бизнеса и иметь...
-
6.1. "Аттестат соответствия" оформляется и выдается после утверждения заключения по результатам проведенных аттестационных испытаний. 6.2. "Аттестат...
-
Основная статья: Операционная система реального времени Применение универсальных компьютеров для управления производственными процессами потребовало...
-
Клиенты, количество реальных пользователей - Система поддержки принятия решений
В настоящее время в области функционирует более 35 автоматизированных рабочих мест. Основное их количество сосредоточено в Министерстве гуманитарного и...
-
Программная документация Модуля включает: Руководство системного программиста; Руководство оператора. Программная документация должна быть оформлена...
-
Разработка элементов интеллектуальных систем с использованием логической модели представления знаний
Разработка элементов интеллектуальных систем с использованием логической модели представления знаний 1. Задание 1 Цель - Знакомство с основами...
Скрипт, определяющий поведение VirtualButton - Разработка системы дополненной реальности с поддержкой распознавания жестов в режиме реального времени