Интеграция с React.js/Vue.js
      Один из самых простых способов интегрировать сцену «Вердж3Д» в ваш проект это загрузить ее отдельно через элемент <iframe>. Но если вы хотите использовать ее непосредственно в своем приложении, то могут возникнуть некоторые трудности. Существует множество возможных конфигураций проекта со своими специфическими проблемами и особенностями. Данное руководство не может охватить их все и ориентировано только на такие популярные «Ява Скрипт»-фреймворки, как React.js и Vue.js.
    
В магазине ассетов «Вержд3Д» имеются готовые демки для React and Vue.js. Однако если вы хотите узнать, как сделать подобное приложение с нуля, читайте дальше.
«Вердж3Д» предлагает пример того, как сделать простой проект "Hello, world!" на React или Vue и интегрировать в него стандартное приложение «Вердж3Д». Файлы примеров находятся в папках manager/templates/Embeddable («Блендер»), manager/templates/Embeddable-Max («3дс Макс»), manager/templates/Embeddable-Maya («Майя») внутри дистрибутива «Вердж3Д».
- Пример приложения «Вердж3Д» на React.js
- Пример приложения «Вердж3Д» на Vue.js
- Использование редактора пазлов
Пример приложения «Вердж3Д» на React.js
Вот простая инструкция о том, как создать базовое приложение React.js + «Вердж3Д» с помощью утилиты Create React App. Вы можете найти копию этой инструкции в manager/templates/Embeddable/README.md внутри дистрибутива «Вердж3Д».
1) Создайте приложение React.js с помощью утилиты Create React App:
    npx create-react-app react-app-example
    
    2) Перейдите в папку react-app-example и установите пакет verge3d:
    cd react-app-example
    npm i verge3d
    
    3) Скопируйте в приложение следующие файлы из дистрибутива «Вердж3Д»:
- содержимое папки manager/templates/Embeddable/public в react-app-example/public
- содержимое папки manager/templates/Embeddable/src в react-app-example/src
или воспользуйтесь командами ниже:
V3D_PATH и MY_PATH это папка дистрибутива «Вердж3Д» и папка приложения соответственно.
    V3D_PATH=/path/to/v3d/distribution
    MY_PATH=/path/to/my/react/app
    cp -r $V3D_PATH/manager/templates/Embeddable/public/* $MY_PATH/public/
    cp -r $V3D_PATH/manager/templates/Embeddable/src/* $MY_PATH/src/
        
      V3D_PATH и MY_PATH это папка дистрибутива «Вердж3Д» и папка приложения соответственно.
    $V3D_PATH = "path\to\v3d\distribution"
    $MY_PATH = "path\to\my\react\app"
    Copy-Item -Path "$V3D_PATH\manager\templates\Embeddable\public\*" -Destination "$MY_PATH\public" -Recurse
    Copy-Item -Path "$V3D_PATH\manager\templates\Embeddable\src\*" -Destination "$MY_PATH\src" -Recurse
        
      4) Создайте файл react-app-example/src/V3DApp.js со следующем содержимым:
    import React from 'react';
    import { createApp } from './v3dApp/app';
    import './v3dApp/app.css';
    class V3DApp extends React.Component {
      #app = null;
      #PL = null;
      #uuid = window.crypto.randomUUID();
      #containerId = `v3d-container-${this.#uuid}`;
      #fsButtonId = `fullscreen-button-${this.#uuid}`;
      #sceneURL = 'v3dApp/app.gltf';
      async loadApp() {
        ({ app: this.#app, PL: this.#PL } = await createApp({
          containerId: this.#containerId,
          fsButtonId: this.#fsButtonId,
          sceneURL: this.#sceneURL,
        }));
      }
      disposeApp() {
        this.#app?.dispose();
        this.#app = null;
        // dispose Puzzles' visual logic
        this.#PL?.dispose();
        this.#PL = null;
      }
      reloadApp() {
        this.disposeApp();
        this.loadApp();
      }
      componentDidMount() {
        this.loadApp();
      }
      componentWillUnmount() {
        this.disposeApp();
      }
      render() {
        return <div id={this.#containerId}>
          <div
            id={this.#fsButtonId}
            className="fullscreen-button fullscreen-open"
            title="Toggle fullscreen mode"
          ></div>
        </div>;
      }
    }
    export default V3DApp;
    
    5) Замените содержимое файла react-app-example/src/index.js следующим кодом:
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import V3DApp from './V3DApp';
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(<V3DApp/>);
    
    6) Запустите сервер разработки, выполнив следующую команду в директории react-app-example:
    npm start
    
    Приложение будет доступно по адресу http://localhost:3000/.
Пример приложения «Вердж3Д» на Vue.js
Вот простая инструкция о том, как создать базовое приложение Vue.js + «Вердж3Д» с помощью утилиты Vue CLI. Вы можете найти копию этой инструкцию в manager/templates/Embeddable/README.md внутри дистрибутива «Вердж3Д».
1) Создайте приложение Vue.js с помощью утилиты Vite:
    npm create vite@latest vue-app-example -- --template vue
    
    2) Перейдите в папку vue-app-example и установите пакет verge3d:
    cd vue-app-example
    npm i verge3d
    
    3) Скопируйте в приложение следующие файлы из дистрибутива «Вердж3Д»:
- содержимое папки manager/templates/Embeddable/public в vue-app-example/public
- содержимое папки manager/templates/Embeddable/src в vue-app-example/src
или воспользуйтесь командами ниже:
V3D_PATH и MY_PATH это папка дистрибутива «Вердж3Д» и папка приложения соответственно.
    V3D_PATH=/path/to/v3d/distribution
    MY_PATH=/path/to/my/vue/app
    cp -r $V3D_PATH/manager/templates/Embeddable/public/* $MY_PATH/public/
    cp -r $V3D_PATH/manager/templates/Embeddable/src/* $MY_PATH/src/
        
      V3D_PATH и MY_PATH это папка дистрибутива «Вердж3Д» и папка приложения соответственно.
    $V3D_PATH = "path\to\v3d\distribution"
    $MY_PATH = "path\to\my\vue\app"
    Copy-Item -Path "$V3D_PATH\manager\templates\Embeddable\public\*" -Destination "$MY_PATH\public" -Recurse
    Copy-Item -Path "$V3D_PATH\manager\templates\Embeddable\src\*" -Destination "$MY_PATH\src" -Recurse
        
      4) Создайте файл vue-app-example/src/components/V3DApp.vue, содержащий следующий код:
    <template>
      <div :id="containerId">
        <div
          :id="fsButtonId"
          class="fullscreen-button fullscreen-open"
          title="Toggle fullscreen mode"
        ></div>
      </div>
    </template>
    <script>
    import { createApp } from '../v3dApp/app';
    export default {
      name: 'V3DApp',
      created() {
        this.app = null;
        this.PL = null,
        this.uuid = window.crypto.randomUUID();
        this.containerId = `v3d-container-${this.uuid}`;
        this.fsButtonId = `fullscreen-button-${this.uuid}`;
        this.sceneURL = 'v3dApp/app.gltf';
        this.loadApp = async function() {
          ({ app: this.app, PL: this.PL } = await createApp({
            containerId: this.containerId,
            fsButtonId: this.fsButtonId,
            sceneURL: this.sceneURL,
          }));
        }
        this.disposeApp = function() {
          this.app?.dispose();
          this.app = null;
          // dispose Puzzles' visual logic
          this.PL?.dispose();
          this.PL = null;
        }
        this.reloadApp = function() {
          this.disposeApp();
          this.loadApp();
        }
      },
      mounted() {
        this.loadApp();
      },
      beforeUnmount() {
        this.disposeApp();
      },
    }
    </script>
    <style>
    @import '../v3dApp/app.css';
    </style>
        
      
        
    <template>
      <div :id="containerId">
        <div
          :id="fsButtonId"
          class="fullscreen-button fullscreen-open"
          title="Toggle fullscreen mode"
        ></div>
      </div>
    </template>
    <script>
    import { createApp } from '../v3dApp/app';
    export default {
      name: 'V3DApp',
      created() {
        this.app = null;
        this.PL = null,
        this.uuid = window.crypto.randomUUID();
        this.containerId = `v3d-container-${this.uuid}`;
        this.fsButtonId = `fullscreen-button-${this.uuid}`;
        this.sceneURL = 'v3dApp/app.gltf';
        this.loadApp = async function() {
          ({ app: this.app, PL: this.PL } = await createApp({
            containerId: this.containerId,
            fsButtonId: this.fsButtonId,
            sceneURL: this.sceneURL,
          }));
        }
        this.disposeApp = function() {
          this.app?.dispose();
          this.app = null;
          // dispose Puzzles' visual logic
          this.PL?.dispose();
          this.PL = null;
        }
        this.reloadApp = function() {
          this.disposeApp();
          this.loadApp();
        }
      },
      mounted() {
        this.loadApp();
      },
      beforeDestroy() {
        this.disposeApp();
      },
    }
    </script>
    <style>
    @import '../v3dApp/app.css';
    </style>
        
      5) Замените vue-app-example/src/App.vue так, чтобы он выглядел следующим образом:
    <template>
      <V3DApp></V3DApp>
    </template>
    <script>
    import V3DApp from './components/V3DApp.vue';
    export default {
      name: 'App',
      components: {
        V3DApp,
      },
    }
    </script>
    
    6) Запустите сервер разработки, выполнив следующую команду в каталоге vue-app-example:
    npm run serve
    
    Приложение должно быть доступно по адресу http://localhost:5173/.
Использование редактора пазлов
Нет прямой интеграции между React/Vue и редактором пазлов/ диспетчером приложений. Тем не менее, вы по-прежнему можете использовать пазлы для добавления сценариев поведения в ваши React/Vue-приложения. В этом разделе объясняется, как это сделать и каковы ограничения данного подхода.
Диспетчер приложений не знает, как может выглядеть структура каталогов типичного проекта React/Vue. Однако после некоторой настройки диспетчер может, по крайней мере, скрипты визуальной логики пазлов. Это означает, что вы можете просматривать соответствующие ресурсы сцены и запускать редактор пазлов из веб-страницы диспетчера приложений.
Недостатком здесь является то, что просмотр файлов .gltf и работа с пазлами может осуществляться только через стандартные приложения «Вердж3Д» созданные внутри диспетчера приложений. Таким образом, нет доступа к React/Vue функциям, компонентам, логике и т.д... и пазлы могут быть добавлены только отдельным образом. Тем не менее, полноценное приложение React/Vue может загружаться, запускаться и взаимодействовать с логическим сценарием, созданным в редакторе пазлов.
Настройка диспетчера приложений
Предположим, у нас есть приложение React или Vue, созданное в соответствии с руководством, описанным в этом справочнике. Для того чтобы "соединить" App Manager и проект React/Vue, нам необходимо создать специальное приложение-адаптер. Имеется шаблон приложения, отсутствующий в диспетчере приложений по умолчанию, но который может быть добавлен в настройках. Для этого используйте руководство по созданию шаблонов и назовите шаблон Embeddable/adapter, введя это имя в поле с именем. Дальше нажмите на кнопку Apply Changes, чтобы добавить новый шаблон:
 
    Далее создайте новое приложение, используя новый шаблон. Назовём его для примера my_awesome_app:
 
    Затем вам потребуется добавить символические ссылки, указывающие на ресурсы внутри проекта React/Vue, чтобы диспетчер приложений мог запустить редактор пазлов. Допустим, ваш проект React/Vue находится по пути MY_PATH, в то время как папка с приложениями по пути V3D_APPS_PATH.
Вы можете узнать, где диспетчер приложений сохраняет приложения, посмотрев настройку App Manager Settings → General → Applications Folder.
Мы создадим символически ссылки указывающие из V3D_APPS_PATH/my_awesome_app/v3dApp на MY_PATH/public/v3dApp — последнее это место, где в проекте React/Vue сохраняются ресурсы «Вердж3Д»-приложения. Также вам потребуется создать пару ссылок на JS и XML файлы логики приложения. Всё это делается следующим образом:
V3D_APPS_PATH и MY_PATH это папка приложений «Вердж3Д» и папка React/Vue приложения соответственно. Также замените my_awesome_app на имя приложения, которое вы указали при его создании в диспетчере приложений.
    V3D_APPS_PATH=/path/to/v3d/applications
    MY_PATH=/path/to/my/app
    ln -s $MY_PATH/public/v3dApp $V3D_APPS_PATH/my_awesome_app/v3dApp
    ln -s $MY_PATH/src/v3dApp/visual_logic.js $V3D_APPS_PATH/my_awesome_app/visual_logic.js
    ln -s $MY_PATH/src/v3dApp/visual_logic.xml $V3D_APPS_PATH/my_awesome_app/visual_logic.xml
        
      Следующие команды PowerShell требуют привилегий администратора.
V3D_APPS_PATH и MY_PATH это папка приложений «Вердж3Д» и папка React/Vue приложения соответственно. Также замените my_awesome_app на имя приложения, которое вы указали при его создании в диспетчере приложений.
    $V3D_APPS_PATH = "path\to\v3d\applications"
    $MY_PATH = "path\to\my\app"
    cmd /c mklink /D $V3D_APPS_PATH\my_awesome_app\v3dApp (Resolve-Path $MY_PATH\public\v3dApp)
    cmd /c mklink $V3D_APPS_PATH\my_awesome_app\visual_logic.js (Resolve-Path $MY_PATH\src\v3dApp\visual_logic.js)
    cmd /c mklink $V3D_APPS_PATH\my_awesome_app\visual_logic.xml (Resolve-Path $MY_PATH\src\v3dApp\visual_logic.xml)
        
      Теперь вы можете увидеть свой проект в диспетчере приложений и использовать редактор пазлов.
 
    Loading Resources in Puzzles
Пазлы replace texture, load scene, load sound, load video, load data, и др. требуют указания УРЛ-адреса с загружаемым ресурсам (текстурам, звукам и т.д.).
При использовании редактора пазла для разработки React/Vue-приложений все пути для данных пазлов рассчитываются относительно корня приложения, который обычно начинается с папки приложения public. Если редактор пазлов используется так как это описано выше, то он имеет доступ только к папке приложения public/v3dApp.
В частности, если нам нужно загрузить звук с помощью пазлов, этот файл, назовём его sound.mp3, должен быть размещён в папке public/v3dApp (или какой-либо его подпапке). После этого он может быть загружен по пути v3dApp/mySound.mp3, который и должен быть указан как УРЛ в пазле load sound:
