Найти тему
Иван Зотов

Творческий подход со встроенной геометрией(продолжение)

Оглавление

Модель простого игрушечного поезда

Надеюсь, что, учитывая все эти разговоры о ротациях, построить поезд будет легко, так что приступим. Мы также будем использовать эту простую модель как возможность создать шаблон для будущих, более сложных компонентов сцены. С этой целью мы создадим отдельные модули для геометрии, материалов и сеток, а затем создадим класс Train для координации других модулей и предоставления минимального интерфейса для использования в World.

Если вам это кажется знакомым, это потому, что это микрокосмос того, как мы настраиваем приложение World. На это есть две причины:

  1. Знакомство: чем больше схожих отдельных разделов нашего кода, тем меньше нам нужно думать при переключении фокуса.
  2. Возможность повторного использования: точно так же, как мы хотим передать папку World / другому разработчику с одним параграфом инструкций о том, как ее использовать, мы хотим иметь возможность копировать Train / компонент между нашими приложениями с нулевыми усилиями.

С другой стороны, эта структура не подойдет для всех возможных компонентов, которые вы создаете. Всегда следите за тем, чтобы структура вашего кода поддерживала то, что вы пытаетесь построить, а не заставляла вас бороться с этим.

В редакторе мы удалили модуль meshGroup.js из предыдущей главы и заменили его новой папкой components / Train /. Если вы работаете на своей машине, сделайте это сейчас. Внутри этой папки четыре модуля:

  • components/Train/geometries.js
  • components/Train/materials.js
  • components/Train/meshes.js
  • components/Train/Train.js

Начальная структура geometries.js, materials.js и meshes.js

Первые два модуля соответствуют формату, аналогичному формату всех других компонентов и систем, которые мы создали до сих пор.

import { BoxBufferGeometry, CylinderBufferGeometry } from 'three';
function createGeometries() {}
export { createGeometries }

import { MeshStandardMaterial } from 'three';
function createMaterials() {}
export { createMaterials }

Наконец, модуль сеток. Это похоже на два других, однако для сеток потребуются геометрии и материалы, созданные двумя другими модулями, поэтому импортируйте их в верхней части модуля, после того, как мы импортируем сетку из ядра three.js (импорт поставщиков всегда будет идти раньше нашего местного импорта). Наконец, вызовите каждую функцию и сохраните результаты в переменных геометрии и материалов.

import { Mesh } from 'three';
import { createGeometries } from './geometries.js';
import { createMaterials } from './materials.js';
function createMeshes() {
const geometries = createGeometries();
const materials = createMaterials();
}
export { createMeshes }

Класс Train расширяет группу

Затем класс Train. Здесь мы сделаем что-то новое и расширим класс Group:

import { Group } from 'three';
class Train extends Group {
constructor() {
super();
}
}
export { Train }

Обратите внимание на использование super (). Это означает, что класс Train теперь имеет все обычные функции группы. В частности, мы можем добавлять к нему объекты, и мы можем добавлять его прямо в нашу сцену:

const train = new Train();
// we can add objects to our train
train.add(mesh);
// and we can add the train directly to the scene
scene.add(train);

Мы также можем получить доступ к объектам добавления в поезд из самого класса, используя this.add:

class Train extends Group {
constructor() {
super();
const mesh = new Mesh(...);
this.add(mesh);
}
}

Импортируйте сетки

Используя эти знания, мы можем закончить настройку класса Train. Сначала импортируйте функцию createMeshes, затем вызовите ее и сохраните результат в переменной-члене this.meshes. В самом конце этой главы мы добавим анимацию колесам, что означает, что нам нужно получить доступ к сеткам извне конструктора, поэтому мы используем здесь переменную-член.

import { Group } from 'three';
import { createGeometries } from './geometries.js';
import { createMaterials } from './materials.js';
import { createMeshes } from './meshes.js';
class Train extends Group {
constructor() {
super();
this.meshes = createMeshes();
}
}
export { Train };

Настройка World.js

В World импортируйте класс Train. Если вы работаете с кодом из предыдущей главы, удалите все ссылки на meshGroup из файла.

import { createCamera } from './components/camera.js';
import {
createAxesHelper,
createGridHelper,
} from './components/helpers.js';
import { createLights } from './components/lights.js';
import { createScene } from './components/scene.js';
import { Train } from './components/Train/Train.js';
import { createControls } from './systems/controls.js';
import { createRenderer } from './systems/renderer.js';
import { Resizer } from './systems/Resizer.js';
import { Loop } from './systems/Loop.js';

Затем создайте экземпляр поезда и добавьте его в сцену.

constructor(container) {
camera = createCamera();
renderer = createRenderer();
scene = createScene();
loop = new Loop(camera, scene, renderer);
container.append(renderer.domElement);
const controls = createControls(camera, renderer.domElement);
const { ambientLight, mainLight } = createLights();
const train = new Train();
scene.add(ambientLight, mainLight, train);
const resizer = new Resizer(container, camera, renderer);
scene.add(createAxesHelper(), createGridHelper());
}

Прочие изменения

Обратите внимание, что мы также внесли некоторые незначительные изменения в положение камеры в camera.js, немного переместили controls.target в controls.js, чтобы лучше кадрировать поезд, а также снизили интенсивность обоих источников света в lights.js.

Создайте материалы

На этом мы закончили создание структуры нашего нового компонента сцены. Все, что осталось, - это настроить материалы, геометрию и сетки. Они не обязательно должны иметь форму поезда. Вы можете использовать эту структуру в качестве шаблона для создания любой формы, о которой только можете мечтать.

Мы создадим два материала для поезда: темно-серый материал для дымохода и колес и красноватый материал для корпуса. Мы будем использовать MeshStandardMaterial с включенным .flatShading для обоих. Кроме .flatShading здесь нет ничего нового. Вот полный модуль материалов:

import { MeshStandardMaterial } from 'three';
function createMaterials() {
const body = new MeshStandardMaterial({
color: 'firebrick',
flatShading: true,
});
const detail = new MeshStandardMaterial({
color: 'darkslategray',
flatShading: true,
});
return { body, detail };
}
export { createMaterials };

Мы выбрали красный огнеупорный для корпуса и темно-серый для колес и дымохода, но вы можете просмотреть список цветов CSS и выбрать два, которые вам нравятся. В конце модуля мы возвращаем объект, содержащий оба материала, для использования в meshes.js.

Продолжение в следующей статье...