I am a college student, working diligently on this project in his free time. If DustyEngine has helped you in any way, please donate just $1!
The purpose of this tutorial will be to explain the new entity system for Dusty Engine that was implemented with release 8 of DE. The entity system allows a flexible, powerful way to control objects on the screen, through the backbone of the Task Engine that Dusty Engine provides.
This tutorial is divided into two sections. In the first section (below,) I will explain the transformations that a Dusty Engine Entity is capable of imposing upon an Irrlicht scene node. In the second section, we will code a small program using the Entities. Click Here For Part 2.
I will begin with an overview of the Entity system provided by Dusty Engine and it's capabilities.
The entity system provided by Dusty Engine is a group of tasks that are created for the sole purpose of controlling the transformations of an object on screen. Three transformations are possible: rotation, scale, and position.
Each of these transformations can be manipulated by the entity in one of 4 ways:1. Vector Manipulation. The rotation, scale, and position of an object are all represented by 3d vectors. Vector manipulation allows the programmer to set a vector into the entity that will be added to one of these transformations every time Dusty Engine updates (which is a controllable amount of time).
For instance, say I want to move an irrlicht node on screen by the vector(1,1,1) every 20 milliseconds.
Entity * myEntity = dustyDriver->CreateEntity(); myEntity->SetNode(node); // always set the type of manipulation before setting manipulation values myEntity->SetMoveType(VECTOR); myEntity->SetMoveVector(vector3df(1,1,1)); |
Now all I have to do is call TaskTree::DoUpdates() in my main loop, and every 20 milliseconds the entity will change position by (1,1,1). 20ms is the default time between entity updates, and this value can be changed by calling Entity::SetUpdateInterval(). Notice I don't have to destroy the entity. In the tradition of Irrlicht's internal management, Dusty Engine always cleans itself up, so long as you use its methods for allocating entities.
Note that I'm using movement in my examples, but this could apply just as well to scaling and rotation.
2. Bounded Manipulation. Bounded manipulation works exactly as Vector Manipulation works in that it will add a certain vector the node's transformation every update. However, the bounded manipulation allows you to set a minimum and maximum boundary on the transformation you are doing.
Lets say I have an entity that I wish to allow to move about freely, but remain within the boundary (-1,-1,-1) and (1,1,1).
myEntity->SetMoveType(BOUNDED); myEntity->SetMoveBoundaries(vector3df(-1,-1,-1), vector3df(1,1,1)); myEntity->SetMoveVector(moveVector); |
This code will cause the entity to remain within those boundaries. You set the movement vector just as you do for VECTOR transformation.
3. Interpolated Manipulation. Interpolated manipulation makes uses of Dusty Engine's built-in interpolation tasks to transform a node's position, scale, or rotation between two points over a given amount of time. The tasks are also capable of looping the node, either back from the beginning once it reaches the end, or back TO the beginning once it reaches the end.
If a have a node that I want to move from point (-1, -1, -1) to point (1, 1, 1) over 5 seconds, I use this code.
myEntity->SetMoveType(INTERPOLATED); myEntity->SetMoveStartPoint(vector3df(-1,-1,-1)); myEntity->SetMoveEndPoint(vector3df(1,1,1)); myEntity->SetMoveInterpolationTime(5000); |
So now that node will move over 5 seconds between those two points. To have it start back at the beginning once it reaches that point:
// this causes the entity to loop once it reaches the end, starting // immediately back at the beginning myEntity->SetMoveLooping(true); |
And to have it loop back to the beginning once it reaches the end:
// this causes the entity to loop back to the beginning in reverse once it // reaches the end, and then start again myEntity->SetMoveReverseLooping(true); |
4. Waypoint Manipulation. The Waypoint manipulation is an extension of Interpolated transformation. It allows you to string together a list of points as "waypoints" and the time between them. The node will then transform between each of those points based upon the amount of time given between them. It can loop just as the Interpolation does, either no looping, start over from the beginning when it reaches the end, or loop back to the beginning when it reaches the end.
Imagine I have a node that I want to move from point(0,0,0) to (1,1,1) in 2 seconds, then to (5,5,5) in another 4 seconds, then to (-1,-1,-1) after another 10 seconds.
myEntity->SetMoveType(WAYPOINT); // Use 0 time for the first point // AddWaypoint(point, time in ms) myEntity->AddMoveWaypoint(vector3df(0,0,0), 0); myEntity->AddMoveWaypoint(vector3df(1,1,1), 2000); myEntity->AddMoveWaypoint(vector3df(5,5,5), 4000); myEntity->AddMoveWaypoint(vector3df(-1,-1,-1), 10000); |
The entity will now move accordingly. I use these functions to set looping:
// loop back from the beginning once the end is reached myEntity->SetMoveWaypointLooping(true) // loop back TO the beginning once the end is reached myEntity->SetMoveWaypointReverseLooping(true); |
This is a question that I have thought about and been faced with in the past. Most of Dusty Engine's built-in tasks are created to transform scene nodes. The entity is just a group of these transformation tasks, which are all placed together and controlled to allow flexibility. So why wouldn't I just a node animator for these transformation effects? The answer comes with Dusty Engine's task pausing and unpausing abilities. DE internally manages changes in time with very precise accuracy, using a class called DeltaTimer. The delta timer maintains changes in time on the millisecond level.
DE's Task Tree is very careful about managing changes in time. This is so that Dusty Engine can have a precise method for pausing and unpausing tasks. When a task is paused, it does not matter how much time passes while it is paused. When it is unpaused, it will pick up IMMEDIATELY where it left off.
For things like interpolation, this is a huge advantage. What happens if you are interpolating a node from one position to another, and the player presses 'p' to pause the game? Well you're out of luck if you don't ignore the time that passes while the game is paused.
Dusty Engine, however, will pick up every task, even interpolation and waypoint tasks, seamlessly when they are unpaused. The tree structure of DE allows you to pause sections of the game while the rest keep running normally, also. This group control of tasks on the tree is the heart of Dusty Engine.
In the next portion of the Tutorial, we will write a program using entities.
On to the Part 2!