This page has been translated automatically.
Unigine Basics
1. Introduction
2. Managing Virtual Worlds
3. Preparing 3D Models
4. Materials
5. Cameras and Lighting
7. Making Cutscenes and Recording Videos
8. Preparing Your Project for Release
9. Physics
10. Optimization Basics
11. PROJECT2: First-Person Shooter
12. PROJECT3: Third-Person Cross-Country Arcade Racing Game
13. PROJECT4: VR Application With Simple Interaction

Moving and Rotating an Object

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.

The following code shows how basic node transformations are performed:

Source code (C++)
// injecting Unigine namespace to the global namespace
using namespace Unigine;
using namespace Unigine::Math;

// move the node by X, Y, Z units along the corresponding axes
node->setWorldPosition(node->getWorldPosition() + Vec3(X, Y, Z));

// move the node by one unit along the Y axis
node->worldTranslate(0.0f, 1.0f, 0.0f);

// rotate the node around the axis (X, Y, Z) by the Alpha angle 
node->setWorldRotation(node->getWorldRotation() * quat(Vec3(X, Y, Z), Alpha));

// rotate the node around X, Y, and Z axes by the corresponding angle (angle_X, angle_Y, angle_Z)
node->setWorldRotation(node->getWorldRotation() * quat(angle_X, angle_Y, angle_Z));

// rotate the node by 45 degrees along the Z axis
node->worldRotate(0.0f, 0.0f, 45.0f);

// orient the node using a direction vector and a vector pointing upwards
node->setWorldDirection(vec3(0.5f, 0.5f, 0.0f), vec3_up, AXIS_Y);

// setting node scale to Scale_X, Scale_Y, Scale_Z along the corresponding axes
node->setWorldScale(vec3(Scale_X, Scale_Y, Scale_Z));

// setting new transformation matrix to scale the node 2 times along all axes, rotate it by 45 degrees around the Z-axis and move it by 1 unit along all axes
Mat4 transform = Mat4(translate(vec3(1.0f, 1.0f, 1.0f)) * rotate(quat(0.0f, 0.0f, 1.0f, 45.0f)) * scale(vec3(2.0f)));

// setting node transformation matrix relative to its parent
node->setTransform(transform);

// setting node transformation matrix relative to the world origin
node->setWorldTransform(transform);

Practice#

Let's add a fan to our scene and try to breathe life into it:

  1. 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.
  2. 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.

  3. Now, let's write a component that will rotate its blades. Create a new component, name it Fan and write the following code:

    Fan.h
    #pragma once
    #include <UnigineComponentSystem.h>
    class Fan :
    	public Unigine::ComponentBase
    {
    public:
    	// declare constructor and destructor for our class and define the name of the property to be associated with the component.
    	// The Fan.prop file containing all parameters listed below will be generated in your project's data folder after running the app for the first time
    	COMPONENT_DEFINE(Fan, ComponentBase);
    
    	// declaration and initialization of component parameters
    	PROP_PARAM(Node, fan_node, nullptr);			// fan blades node to be rotated
    	PROP_PARAM(Float, speed, 720.0f);			// rotation speed
    
    	// registering methods to be called at the corresponding stages of the world logic (methods are declared in the protected-section below)
    	COMPONENT_UPDATE(update);
    
    protected:
    	// declaration of methods to be called at the corresponding stages of the world logic
    	void update();
    };
    Fan.cpp
    #include "Fan.h"
    
    // registering the Fan component
    REGISTER_COMPONENT(Fan);
    
    // injecting necessary namespaces
    using namespace Unigine;
    using namespace Math;
    
    // component's update method to be called each frame
    void Fan::update()
    {
    	// if the fan blades node is not assigned, nothing happens
    	if (!fan_node)
    		return;
    	// rotate the node with the specified speed
    	fan_node->rotate(0, speed, 0);
    }
  4. Let's save our files and then build and run our application by hitting Ctrl + F5 to make the Component System generate a property to be used to assign our component to nodes. Close the application after running it and switch to UnigineEditor.

    Create NodeDummy, name it fan_rotator, and assign our new generated Fan property 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.

  5. 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.
  6. Then we should disable the fan_rotator node, to prevent the code of the component that rotates the fan blades from execution until we turn the switch on.
  7. We're going to rotate the fan_table_propeller node, by default it's Mobility is set to Immovable, so we have to switch it to Dynamic.

  8. Save the world by hitting Ctrl + S. Switch to SDK Browser and launch our application by clicking the Run button on our project's card to see the result.

Last update: 2024-11-06
Build: ()