Перемещение и вращение объектов
The objects existing in the virtual world are often moving somewhere and rotating, in general, transforming. Each node has a transformation matrix that encodes its position, rotation, and scale in the world. If a node is a child of another node (part of its hierarchy), it has a transformation matrix associated with the parent (local). This is why the Node class has two different properties: Transform and WorldTransform, which handle local and world transformation matrices respectively.Существующие в виртуальном мире объекты то и дело куда-то движутся, поворачиваются – в общем – трансформируются. Каждая нода имеет матрицу трансформации, которая кодирует ее положение, поворот и масштаб в мире. Если нода является дочерней для другой ноды (входит в ее иерархию), она имеет матрицу преобразования, связанную с родительской (локальную). Вот почему класс Node имеет разные свойства: Transform и WorldTransform, которые работают с локальными и мировыми матрицами трансформации соответственно.
The following code shows how basic node transformations are performed:Следующий код показывает, как выполняются базовые преобразования нод:
// перемещение ноды на X, Y, Z единиц вдоль соответствующих осей
node.WorldPosition = node.WorldPosition + new vec3(X, Y, Z);
// перемещение ноды на 1 единицу по оси Y
node.WorldTranslate(0.0f, 1.0f, 0.0f);
// поворот ноды вокруг оси (X, Y, Z) на угол Alpha
node.SetWorldRotation(node.GetWorldRotation() * new quat(new vec3(X, Y, Z), Alpha));
// поворот ноды вокруг осей X, Y и Z на соответствующие углы (angle_X, angle_Y, angle_Z)
node.SetWorldRotation(node.GetWorldRotation() * new quat(angle_X, angle_Y, angle_Z));
// поворот ноды на 45 градусов вокруг оси Z
node.WorldRotate(0.0f, 0.0f, 45.0f);
// поворот ноды с использованием вектора direction (направление) и вектора, показывающего вверх
node.SetWorldDirection(new vec3(0.5f, 0.5f, 0.0f), vec3.UP, MathLib.AXIS.Y);
// установка масштаба ноды в Scale_X, Scale_Y, Scale_Z по соответствующим осям
node.WorldScale = new vec3(Scale_X, Scale_Y, Scale_Z);
// установка новой матрицы трансформации для увеличения масштаба ноды в 2 раза по всем осям,
// поворота на 45 градусов вокруг оси Z и перемещения на 1 единицу по всем осям
dmat4 transform = new dmat4(MathLib.Translate(1.0f, 1.0f, 1.0f)
* MathLib.Rotate(new quat(0.0f, 0.0f, 1.0f, 45.0f))
* MathLib.Scale(new vec3(2.0f)));
// установка матрицы трансформации ноды относительно ее родителя
node.Transform = transform;
// установка матрицы трансформации ноды относительно глобального начала координат
node.WorldTransform = transform;
PracticeПрактика#
Let's add a fan to our scene and try to breathe life into it:Давайте добавим в сцену вентилятор и попробуем вдохнуть в него жизнь:
- Open the archviz/interior/fan folder in the Asset Browser, drag the fan asset fan.fbx to the scene and place it on the table near the bed.Откройте папку archviz/interior/fan в Asset Browser, перетащите ассет вентилятора fan.fbx на сцену и установите его на прикроватном столике.
-
Open the archviz/interior/fan/materials folder and drag the fan_body_mat_0 material to the fan body, and the fan_propeller_mat_0 material — to the blades.Откройте папку archviz/interior/fan/materials и перетащите материал fan_body_mat_0 на корпус вентилятора, а материал fan_propeller_mat_0 - на лопасти.
-
Now, let's write a component that will rotate its blades. Create a new component, name it Fan and write the following code:А теперь напишем компонент, который будет вращать его лопасти. Создадим новый компонент, назовем его Fan и напишем следующий код:
using System; using System.Collections; using System.Collections.Generic; using Unigine; [Component(PropertyGuid = "AUTOGENERATED_GUID")] // <-- идентификатор генерируется автоматически для нового компонента public class Fan : Component { public Node fan_node = null; public float speed = 10.0f; private void Update() { // если не назначена нода лопастей, ничего не делаем if(!fan_node) return; // поворачиваем ноду с заданной скоростью fan_node.Rotate(0, speed, 0); } }
-
Create NodeDummy, name it fan_rotator, and assign the Fan component to it. Customize the Fan component by dragging the fan_table_propeller node into the Fan Node field and setting the rotation speed of the blades.Создадим ноду NodeDummy и назовем ее fan_rotator, и на нее назначим компонент Fan. Настроим компонент Fan, перетащив ноду fan_table_propeller в поле Fan Node и установив скорость вращения лопастей.
- Let's add fan_rotator to the child nodes of fan_table, assign the Toggle component to the fan_table_switch node, and drag the fan_rotator node into the Control Node field.Добавим fan_rotator в дочерние ноды к fan_table, затем на ноду fan_table_switch назначим компонент Toggle и, наконец, перетащим в поле Control Node ноду fan_rotator.
- Now we can press Play and check the result.Теперь можно жать на Play и смотреть, что получилось.