Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Моделі рендерингу OpenXR

Наріжним каменем дизайну API OpenXR є максимально можлива платформонезалежність. Чудовим прикладом цього є система карт дій OpenXR, де середовища виконання XR повинні підтримувати основні профілі взаємодії, до яких можна повернутися, якщо для використовуваного обладнання не існує профілю взаємодії. Це гарантує, що програми OpenXR продовжуватимуть функціонувати навіть під час використання на обладнанні, якого не існувало на момент випуску програми, або до якого розробники програми не мали доступу.

Наслідком цього є те, що розробник застосунку не знає з певністю, яке обладнання використовується, оскільки середовище виконання XR може імітувати інше обладнання. Таким чином, розробник застосунку не може показати нічого, що стосується фактично використаного обладнання, найпоширенішим випадком використання є показ контролерів, які користувач наразі тримає.

Для належного відчуття занурення важливо відобразити правильні моделі контролерів та їх правильне розташування.

Саме тут і з'являється API моделей рендерингу OpenXR <https://registry.khronos.org/OpenXR/specs/1.1/html/xrspec.html#XR_EXT_render_models>`_. Цей API дозволяє нам запитувати середовище виконання XR на наявність 3D-ресурсів, які відповідають використовуваному фізичному обладнанню. API також дозволяє нам запитувати положення цього обладнання в об'ємі відстеження та правильне розташування підкомпонентів цього обладнання.

Наприклад, ми можемо правильно розташувати та анімувати тригер або відображати натискання кнопок.

Для тих середовищ виконання, що підтримують джерело даних контролера для відстеження руки, ми також можемо правильно розташувати пальці та руку користувача відповідно до форми контролера. Зверніть увагу, що це працює в поєднанні з розширенням діапазону руху суглобів кисті, щоб запобігти обрізанню пальців.

Вузол моделей рендерингу OpenXR

Вузол OpenXRRenderModelManager можна використовувати для автоматизації більшості функцій моделей рендерингу. Цей вузол відстежує активні моделі рендерингу, які наразі доступні у середовищі виконання XR.

Він створить дочірні вузли для кожної активної моделі рендерингу, що призведе до відображення цієї моделі рендерингу.

Цей вузол повинен мати вузол XROrigin3D як предка.

Якщо для параметра tracker встановлено значення Any, наш вузол показуватиме всі моделі рендерингу, які наразі відстежуються. У цьому сценарії цей вузол має бути прямим дочірнім елементом нашого вузла XROrigin3D.

Якщо для параметра tracker встановлено значення None set, наш вузол показуватиме лише ті моделі рендерингу, для яких не було ідентифіковано трекер. У цьому сценарії цей вузол також має бути прямим дочірнім елементом нашого вузла XROrigin3D.

Якщо для параметра tracker встановлено значення Left Hand або Right Hand, наш вузол відображатиме лише моделі рендерингу, пов'язані з нашою лівою або правою рукою відповідно. У цьому випадку наш вузол можна розмістити глибше в дереві сцени.

Попередження

Для більшості середовищ виконання XR це означає, що модель рендерингу представляє контролер, який фактично тримає користувач, але це не гарантовано. Деякі середовища виконання XR завжди встановлюють трекер на ліву або праву руку, навіть якщо контролер наразі не тримається, але відстежується. Вам завжди слід перевіряти це, оскільки це призведе до небажаної поведінки.

У цьому сценарії ми також можемо вказати дію для пози на карті дій, встановивши властивість make_local_to_pose для дії пози. Використовуйте це в поєднанні з вузлом XRController3D, який використовує ту саму позу, і тепер ви можете додати шар, який дозволить вам відхилятися від відстеженої позиції як вашого контролера, так і пов'язаної з ним моделі рендерингу (див. приклад нижче).

Примітка

Поєднання вищезазначеного з відстеженням рук створює проблему, оскільки відстеження рук повністю незалежне від системи карти дій. Вам потрібно буде поєднати відстеження рук та відстеження пози контролера, щоб правильно змістити моделі рендерингу.

Це виходить за рамки цієї документації.

Приклад менеджера моделей рендерингу

Ви можете завантажити нашу демонстраційну версію моделей рендерингу, яка реалізує описану нижче налаштування.

../../_images/openxr_render_models_setup.webp

У цій конфігурації ми знаходимо вузол OpenXRRenderModelManager безпосередньо під нашим вузлом XROrigin3D. На цьому вузлі наша властивість target встановлена на None set і оброблятиме відображення всіх моделей рендерингу, які наразі не пов'язані з нашими лівим або правим контролерами.

Потім ми бачимо однакову конфігурацію для лівої та правої руки, тому зосередимося лише на лівій руці.

У нас є XRController3D, який відстежуватиме місцезнаходження нашої руки.

Примітка

Ми використовуємо grip поза в цьому прикладі. palm поза, можливо, більш підходяща та передбачувана, проте вона підтримується не всіма середовищами виконання XR. Дивіться демонстраційний проект відстеження рук, щоб знайти рішення для перемикання між цими позами залежно від того, що підтримується.

Як дочірній елемент вузла, у нас є вузол AnimatableBody3D, який слідкує за відстежуваним розташуванням руки, але взаємодіятиме з фізичними об'єктами, щоб запобігти проходженню руки гравця крізь стіни тощо. Цей вузол має форму зіткнення, яка інкапсулює руку.

Примітка

Важливо встановити пріоритет фізики таким чином, щоб ця логіка виконувалася після будь-якої фізичної логіки, яка переміщує вузол XROrigin3D, інакше рука відставатиме на кадр.

Наведений нижче скрипт показує базову реалізацію, на якій ви можете будувати далі.

class_name CollisionHands3D
extends AnimatableBody3D

func _ready():
    # Make sure these are set correctly.
    top_level = true
    sync_to_physics = false
    process_physics_priority = -90

func _physics_process(_delta):
    # Follow our parent node around.
    var dest_transform = get_parent().global_transform

    # We just apply rotation for this example.
    global_basis = dest_transform.basis

    # Attempt to move to where our tracked hand is.
    move_and_collide(dest_transform.origin - global_position)

Нарешті ми бачимо ще один вузол OpenXRRenderModelManager, цього разу з target, встановленим на відповідну руку, та make_local_to_pose, встановленим на правильну позу. Це гарантуватиме, що моделі рендерингу, пов'язані з цією рукою, будуть правильно відображені та зміщені, якщо наш обробник колізій змінив розташування.

Вузол рендерингу моделі

Вузол OpenXRRenderModel реалізує всю логіку для відображення та позиціонування заданої моделі рендерингу, що надається API моделей рендерингу.

Екземпляри цього вузла додаються вузлом менеджера моделей рендерингу, який ми використовували вище, але ви можете взаємодіяти з ними безпосередньо, якщо бажаєте.

Щоразу, коли Godot отримує інформацію про нову модель рендерингу, створюється RID для посилання на цю модель рендерингу.

Призначивши цей RID властивості render_model цього вузла, вузол почне відображати модель рендерингу та керувати як перетворенням, яке розміщує модель рендерингу в правильному місці, так і анімує всі підоб'єкти.

Функція get_top_level_path поверне шлях верхнього рівня, пов'язаний з цією моделлю рендерингу. Він вказуватиме на ліву або праву руку. Оскільки шлях верхнього рівня можна встановити або очистити залежно від того, чи користувач бере контролер, чи опускає його, ви можете підключитися до сигналу render_model_top_level_path_changes та реагувати на ці зміни.

Залежно від налаштувань вузлів OpenXRRenderModelManager, моделі рендерингу будуть видалятися або додаватися, коли змінюється шлях їхнього верхнього рівня.

Доступ до серверної частини

Вузли, які ми детально описали вище, обробляють всю логіку відображення, але ви можете взаємодіяти з даними, які безпосередньо цим керують, і створювати власну реалізацію.

Для цього ви можете отримати доступ до синглтона OpenXRRenderModelExtension.

Цей об'єкт також дозволяє запитувати, чи підтримуються та чи ввімкнені моделі рендерингу на пристрої, що використовується на даний момент, викликаючи функцію is_active на цьому об'єкті.

Вбудована логіка реалізує interaction render model API, який відображає список усіх моделей рендерингу, пов'язаних з контролерами та подібними пристроями, присутніми на карті дій. Він автоматично створюватиме та видалятиме сутності моделей рендерингу, що відображаються через цей API.

Коли з'являться інші розширення, їх можна буде реалізувати в плагіні GDExtension. Такий плагін може викликати render_model_create та render_model_destroy для створення об'єкта, який надаватиме доступ до цієї моделі рендерингу через основний API моделей рендерингу.

Не слід знищувати модель рендерингу поза цією логікою.

Ви можете підключитися до сигналів render_model_added та render_model_removed, щоб отримувати інформацію про додавання або видалення нових моделей рендерингу.

Основні методи роботи з цим API перелічені нижче:

Функції розширення моделей візуалізації

Function

Опис

render_model_get_all

Надає масив RID для всіх моделей рендерингу, які відстежуються.

render_model_new_scene_instance

Надає нову сцену, яка містить усі сітки, необхідні для відображення моделі рендерингу.

render_model_get_subaction_paths

Надає список шляхів піддій з вашої карти дій, пов'язаних з цим режимом рендерингу.

render_model_get_top_level_path

Повертає шлях верхнього рівня, пов'язаний з цією моделлю рендерингу (якщо така є). Використовуйте сигнал render_model_top_level_path_changed для реагування на цю зміну.

render_model_get_confidence

Повертає впевненість відстеження для даних відстеження для цієї моделі рендерингу.

render_model_get_root_transform

Повертає кореневе перетворення для цієї моделі візуалізації в межах нашого поточного простору відліку. Це можна використовувати для розміщення моделі візуалізації в просторі.

render_model_get_animatable_node_count

Повертає кількість вузлів у нашій сцені моделі рендерингу, які можна анімувати

render_model_get_animatable_node_name

Повертає назву вузла, який ми можемо анімувати. Зверніть увагу, що цей вузол може бути на будь-якій кількості рівнів глибини в сцені.

render_model_is_animatable_node_visible

Повертає значення true, якщо цей анімований вузол має бути видимим

render_model_get_animatable_node_transform

Повертає перетворення для цього анімованого вузла. Це локальне перетворення, яке можна застосувати безпосередньо.