3D - Rete.js

3D

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

3DДекілька 3D редакторівThree.jsПлагін

У цьому гайді описано, як включити редактор вузлів у 3D-сцену. Це можна досягти за допомогою rete-area-3d-plugin, який замінює стандартний rete-area-plugin.

Архітектура

Завдяки Three.js цей плагін створює сцену, яка містить камеру та два рендерери – CSS3DRenderer і WebGLRenderer. Отже, 3D-об’єкти та нативні HTML-елементи відображаються разом в одному в’юпорті, з можливістю перекриття. Основна перевага використання нативних елементів (на відміну від візуалізації в текстуру) полягає в збереженні повної інтерактивності.

Встановити залежності

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

bash
npm i rete-area-3d-plugin three @types/three

Підключення плагіна

Якщо ви дотримувались базового гайду, вам потрібно буде замінити ініціалізацію Area2DPlugin на Area3DPlugin і змінити деякі визначення типів.

ts
import { Area3D, Area3DPlugin } from 'rete-area-3d-plugin';

type AreaExtra =
  | Area3D<Schemes>

const area = new Area3DPlugin<Schemes, AreaExtra>(container);

editor.use(area);

Отже, контейнер включатиме як елемент <canvas>, так і контейнер для HTML-елементів, які зазнають 3D-трансформації.

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

ts
Area3DExtensions.animate(area)

Це розширення використовує типовий підхід three.js до циклів анімації, використовуючи функцію render() разом із requestAnimationFrame().

Крім того, нам потрібно пов’язати наші вузли та з’єднання з геометрією в 3D-сцені, щоб забезпечити інтерактивну функціональність і запобігти небажаному накладанню з іншими об’єктами.

ts
Area3DExtensions.forms.connection(render);
Area3DExtensions.forms.node(area);

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

Тепер ви можете взаємодіяти з вузлами та обертати або переміщати камеру навколо них. Перегляньте повний результат на сторінці прикладу 3D.

Додаткові розширення

Деякі розширення, доступні у rete-area-plugin, можна використовувати лише в редакторі, не враховуючи в’юпорт та подібні фактори.

ts
import { AreaExtensions } from 'rete-area-plugin'

AreaExtensions.showInputControl(area)
AreaExtensions.simpleNodesOrder(area)
AreaExtensions.snapGrid(area, { size: 30 })
AreaExtensions.selectableNodes(area, AreaExtensions.selector(), { accumulating: AreaExtensions.accumulateOnCtrl() });

У цьому плагіні доступні такі розширення:

ts
import { Area3DExtensions } from 'rete-area-3d-plugin'

Area3DExtensions.forms.comment(area) // створює геометрію для плагіна коментарів
Area3DExtensions.forms.reroute(area) // створює геометрію для плагіна зміни маршруту

Area3DExtensions.lookAt(area, editor.getNodes()) // альтернатива zoomAt від rete-area-plugin

Менеджмент сцени

Сцена

Як було сказано раніше, цей плагін створює сцену з камерою та рендерерами. Щоб отримати доступ до них, ви можете використовувати такий код:

ts
const { scene } = area.area

scene.root // Scene від three.js
scene.camera // PerspectiveCamera
scene.renderer.css3d // CSS3DRenderer
scene.renderer.webgl // WebGLRenderer
scene.orbit // OrbitControls

Наприклад, у вас є можливість вимкнути орбітальний контроль (scene.orbit.enabled = false) і додати альтернативний, або налаштувати параметри рендерів або камери.

Ви можете додавати 3D-об’єкти через scene.root, який є екземпляром Scene у Three.js.

Кастомні HTML елементи

Якщо ви хочете включити HTML-елементи в сцену, зокрема в полотно редактора, використовуйте такий код:

ts
area.area.content.add(element)

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

ts
area.area.content.updateGeometry(element, bufferGeometry)

Перегляньте більше прикладів у вихідному коді

Що стосується інших елементів HTML, він зберігатиме власний порядок, і ви можете змінити його наступним чином:

ts
area.area.content.reorder(element, nextElement)

Видалення елемента:

ts
area.area.content.remove(element)

Кастомізація

Якщо ви кастомізували свої вузли або з’єднання, ви можете помітити, що вони не відповідають заповненню в 3D-сцені. Щоб адаптувати їх до нових форм, ви можете або реалізувати свою власну геометрію, або повторно використовувати існуючу з різними аргументами.

Приклад зміни радіуса межі вузла:

ts
Area3DExtensions.forms.node(area, {
  customize(node) {
    return Area3DExtensions.forms.createClassicNodeGeometry(node, {
      borderRadius: 0
    })
  }
})

Приклад геометрії з'єднання із збільшеною шириною:

ts
Area3DExtensions.forms.connection(reactRender, {
  customize(path) {
    return Area3DExtensions.forms.createClassicConnectionGeometry(path, 10)
  }
})

Декілька редакторів

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

ts
const mainEditor = new NodeEditor<Schemes>();
const mainArea = new Area3DPlugin<Schemes, AreaExtra>(container)

mainEditor.use(mainArea)

const secondaryEditor = new NodeEditor<Schemes>();
const secondaryArea = mainArea.share()

secondaryEditor.use(secondaryArea)

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

ts
const canvas = secondaryArea.area.getCanvas()

canvas.rotateY(Math.PI / 2)
canvas.get(sharedArea)?.translateX(500)

Перегляньте повний результат на сторінці прикладу Декілька 3D-редакторів.