Unigine::Landscape Class
Header: | #include <UnigineObjects.h> |
This class is used to manage landscape terrain rendering and modification.
Terrain modification is performed in asynchronous mode on GPU side by calling a corresponding method, that commences a drawing operation. When calling such a method you should specify the GUID of an .lmap file landscape layer map to be modified, the coordinates of the upper-left corner and the resolution of the segment of data to be modified, you should also define which data layers are to be affected (heights, albedo, masks) via a set of flags. The operation itself is to be implemented inside a callback handler.
GPU-Based Terrain Modification#
The workflow is as follows:
- Implement your GPU-based terrain modification logic in a function.
- Set this handler function when subscribing for the Texture Draw event (when GPU-based terrain modification operation is performed) via getEventTextureDraw().
- Commence a GPU drawing operation by calling the asyncTextureDraw() method.
Here you should specify the GUID of an .lmap file landscape layer map to be modified, the coordinates of the upper-left corner and the resolution of the segment of data to be modified, you should also define which data layers are to be affected (heights, albedo, masks) via a set of flags
In case your modification requires additional data beyond the specified area as well as the data of other landscape layer maps (e.g. a copy brush) you can enable force loading of required data, in this case you should use this overload of the asyncTextureDraw() method.
// GPU-based modification
void my_texture_draw(const UGUID &guid, int id, const LandscapeTexturesPtr &buffer, const Math::ivec2 &coord, int data_mask)
{
// getting the desired brush material (built - in "cirle_soft" Editor's brush)
// and inheriting a child material from it
auto file_guid = FileSystem::getGUID(FileSystem::resolvePartialVirtualPath("circle_soft.brush"));
if (!file_guid.isValid())
{
Log::warning("LandscapePainter::init(): can not find \"circle_soft.brush\" material\n");
return;
}
MaterialPtr brush_material = Materials::findMaterialByFileGUID(file_guid)->inherit();
// setting necessary textures (e.g., albedo and heights)
brush_material->setTexture("terrain_albedo", buffer->getAlbedo());
brush_material->setTexture("terrain_height", buffer->getHeight());
// setting up brush material parameters (size, color, etc. and specifying masks to be affected by the brush)
brush_material->setParameterFloat("size", 100.0f);
brush_material->setParameterFloat("height", 10.0f);
brush_material->setParameterFloat4("color", vec4_green);
brush_material->setParameterInt("data_mask", data_mask);
// running material's "brush" expression
brush_material->runExpression("brush", buffer->getResolution().x, buffer->getResolution().y);
// resetting material textures
brush_material->setTexture("terrain_albedo", nullptr);
brush_material->setTexture("terrain_height", nullptr);
}
// ...
int AppWorldLogic::init()
{
// getting an existing landscape terrain object
ObjectLandscapeTerrainPtr terrain = Landscape::getActiveTerrain();
// getting the first layermap that we're going to modify
LandscapeLayerMapPtr lmap = checked_ptr_cast<LandscapeLayerMap> (terrain->getChild(0));
// subscribing for a Texture Draw operation
Landscape::getEventTextureDraw().connect(connections, my_texture_draw);
// generating a new ID for the draw operation
int id = Landscape::generateOperationID();
// user's code (bounding to ID)
// commencing a Texture Draw operation for the selected landscape map at (1, 1) with the size of [32 x 32]
Landscape::asyncTextureDraw(id, lmap->getGUID(), ivec2(1, 1), ivec2(32, 32), Landscape::FLAGS_DATA_HEIGHT | Landscape::FLAGS_DATA_ALBEDO);
return 1;
}
// ...
int AppWorldLogic::shutdown()
{
// removing all subscriptions
connections.disconnectAll();
return 1;
}
And the process:
- After commencing of a terrain modification operation with all necessary parameters specified, the Engine copies a fragment of terrain data from the specified landscape layer map file at the specified coordinates to a buffer (LandscapeTextures) of the specified resolution.
- Upon completion of the copying process a handler function which you used to subscribe for the TextureDraw event is executed. This function modifies the buffer.
- After this selected data layers of the modified buffer are pasted back to the landscape layer map file.
Usage Example: Brush Editor#
Below is a C++ component implementing brush-based Landscape Terrain modification.
#pragma once
#include <UnigineComponentSystem.h>
#include <UniginePlayers.h>
class LandscapeBrush :
public Unigine::ComponentBase
{
public:
COMPONENT_DEFINE(LandscapeBrush, Unigine::ComponentBase);
COMPONENT_INIT(init);
COMPONENT_UPDATE(update);
COMPONENT_SHUTDOWN(shutdown);
PROP_PARAM(Float, brush_size, 10.0f, "Brush Size");
PROP_PARAM(Float, brush_height, 1.0f, "Brush Height");
private:
void init();
void update();
void shutdown();
void my_texture_draw(const Unigine::UGUID &guid, int id, const Unigine::LandscapeTexturesPtr &buffer, const Unigine::Math::ivec2 &coord, int data_mask);
Unigine::LandscapeLayerMapPtr lmap;
Unigine::PlayerPtr player;
Unigine::LandscapeFetchPtr landscape_fetch;
Unigine::MaterialPtr brush_material;
Unigine::EventConnections connections;
#include "LandscapeBrush.h"
#include <UnigineGame.h>
REGISTER_COMPONENT(LandscapeBrush);
using namespace Unigine;
using namespace Math;
// GPU-based modification
void LandscapeBrush::my_texture_draw(const UGUID &guid, int id, const LandscapeTexturesPtr &buffer, const Math::ivec2 &coord, int data_mask)
{
// setting necessary textures (e.g., albedo and heights)
brush_material->setTexture("terrain_albedo", buffer->getAlbedo());
brush_material->setTexture("terrain_height", buffer->getHeight());
// setting up brush material parameters (size, color, etc. and specifying masks to be affected by the brush)
brush_material->setParameterFloat("size", brush_size);
brush_material->setParameterFloat("height", brush_height);
brush_material->setParameterFloat4("color", Math::vec4_green);
brush_material->setParameterInt("data_mask", data_mask);
// running material's "brush" expression
brush_material->runExpression("brush", buffer->getResolution().x, buffer->getResolution().y);
// resetting material textures
brush_material->setTexture("terrain_albedo", nullptr);
brush_material->setTexture("terrain_height", nullptr);
}
void LandscapeBrush::init()
{
// getting the desired brush material (built - in "cirle_soft" Editor's brush) and inheriting a child material from it
auto guid = FileSystem::getGUID(FileSystem::resolvePartialVirtualPath("circle_soft.brush"));
if (!guid.isValid())
{
Log::warning("LandscapePainter::init(): can not find \"circle_soft.brush\" material\n");
return;
}
brush_material = Materials::findMaterialByFileGUID(guid)->inherit();
// getting an existing landscape terrain object
ObjectLandscapeTerrainPtr terrain = Landscape::getActiveTerrain();
// getting the first layermap that we're going to modify
lmap = checked_ptr_cast<LandscapeLayerMap>(terrain->getChild(0));
// subscribing for the Texture Draw operation
Landscape::getEventTextureDraw().connect(connections, this, &LandscapeBrush::my_texture_draw);
// setting the mouse handling mode to USER to display the cursor on the screen
ControlsApp::setMouseHandle(Input::MOUSE_HANDLE_USER);
// Getting the current player
player = Game::getPlayer();
return;
}
void LandscapeBrush::update()
{
// Write here code to be called before updating each render frame: specify all graphics-related functions you want to be called every frame while your application executes.
// if right mouse button is clicked
if (Input::isMouseButtonDown(Input::MOUSE_BUTTON_RIGHT))
{
landscape_fetch = LandscapeFetch::create();
// getting direction from the current mouse position
Math::ivec2 mouse = Input::getMousePosition();
Math::Vec3 dir = Math::Vec3(player->getDirectionFromMainWindow(mouse.x, mouse.y));
// fetching the coordinates of the point of intersection
bool fetched = landscape_fetch->intersectionForce(player->getPosition(),
player->getPosition() + Vec3(dir) * 10000.0);
if (fetched)
{
// getting the local position of the brush relative to the layer map
Vec3 brush_local_position = lmap->getIWorldTransform() * landscape_fetch->getPosition();
// calculating the bound of the layer map area to be affected by the brush
float half_size = brush_size / 2.0f;
Vec3 brush_local_corners[4] = {
brush_local_position + Vec3(-half_size, -half_size, 0.0),
brush_local_position + Vec3(half_size, -half_size, 0.0),
brush_local_position + Vec3(-half_size, half_size, 0.0),
brush_local_position + Vec3(half_size, half_size, 0.0)
};
auto brush_local_bbox_min = Vec2{
min(min(brush_local_corners[0].x, brush_local_corners[1].x), min(brush_local_corners[2].x, brush_local_corners[3].x)),
min(min(brush_local_corners[0].y, brush_local_corners[1].y), min(brush_local_corners[2].y, brush_local_corners[3].y))
};
auto brush_local_bbox_max = Vec2{
max(max(brush_local_corners[0].x, brush_local_corners[1].x), max(brush_local_corners[2].x, brush_local_corners[3].x)),
max(max(brush_local_corners[0].y, brush_local_corners[1].y), max(brush_local_corners[2].y, brush_local_corners[3].y))
};
// calculating the number of pixels per unit length
auto pixels_per_unit = Vec2{ lmap->getResolution() } / Vec2{ lmap->getSize() };
// calculating the coordinates and the size of the region or the landscape layer texture to be modified
auto drawing_region_coord = ivec2{ pixels_per_unit * brush_local_bbox_min };
auto drawing_region_size = ivec2{ pixels_per_unit * (brush_local_bbox_max - brush_local_bbox_min) };
// user's code (bounding to ID)
auto id = Landscape::generateOperationID();
// commencing a Texture Draw operation for the selected landscape map for the region with the specified coords and size
// affecting Height and Albedo data
Landscape::asyncTextureDraw(id, lmap->getGUID(), drawing_region_coord,
drawing_region_size, Landscape::FLAGS_DATA_HEIGHT | Landscape::FLAGS_DATA_ALBEDO);
}
}
return;
}
void LandscapeBrush::shutdown()
{
// removing all subscriptions
connections.disconnectAll();
return;
}
Landscape Class
Enums
TYPE_DATA#
FLAGS_DATA#
TYPE_FILE_DATA#
File data types.FLAGS_FILE_DATA#
File data layer flags.COMPRESSOR_TYPE#
Compression method used for the layer map.BLENDING_MODE#
Blending mode used for the layer map.Members
bool isFilesClosed() const#
Return value
true if .lmap files for all landscape layer maps are closed is enabled; otherwise false.Event<const UGUID &, int, const char *, const char *> getEventSaveFile() const#
void savefile_event_handler(const UGUID & guid, int operation_id, const char * path_new_state, const char * path_old_state)
Usage Example
// implement the SaveFile event handler
void savefile_event_handler(const UGUID & guid, int operation_id, const char * path_new_state, const char * path_old_state)
{
Log::message("\Handling SaveFile event\n");
}
//////////////////////////////////////////////////////////////////////////////
// 1. Multiple subscriptions can be linked to an instance of the EventConnections
// class that you can use later to remove all these subscriptions at once
//////////////////////////////////////////////////////////////////////////////
// create an instance of the EventConnections class
EventConnections savefile_event_connections;
// link to this instance when subscribing to an event (subscription to various events can be linked)
Landscape::getEventSaveFile().connect(savefile_event_connections, savefile_event_handler);
// other subscriptions are also linked to this EventConnections instance
// (e.g. you can subscribe using lambdas)
Landscape::getEventSaveFile().connect(savefile_event_connections, [](const UGUID & guid, int operation_id, const char * path_new_state, const char * path_old_state) {
Log::message("\Handling SaveFile event (lambda).\n");
}
);
// ...
// later all of these linked subscriptions can be removed with a single line
savefile_event_connections.disconnectAll();
//////////////////////////////////////////////////////////////////////////////
// 2. You can subscribe and unsubscribe via an instance of the EventConnection
// class. And toggle this particular connection off and on, when necessary.
//////////////////////////////////////////////////////////////////////////////
// create an instance of the EventConnection class
EventConnection savefile_event_connection;
// subscribe to the SaveFile event with a handler function keeping the connection
Landscape::getEventSaveFile().connect(savefile_event_connection, savefile_event_handler);
// ...
// you can temporarily disable a particular event connection to perform certain actions
savefile_event_connection.setEnabled(false);
// ... actions to be performed
// and enable it back when necessary
savefile_event_connection.setEnabled(true);
// ...
// remove subscription to the SaveFile event via the connection
savefile_event_connection.disconnect();
//////////////////////////////////////////////////////////////////////////////
// 3. You can add EventConnection/EventConnections instance as a member of the
// class that handles the event. In this case all linked subscriptions will be
// automatically removed when class destructor is called
//////////////////////////////////////////////////////////////////////////////
// Class handling the event
class SomeClass
{
public:
// instance of the EventConnections class as a class member
EventConnections e_connections;
// A SaveFile event handler implemented as a class member
void event_handler(const UGUID & guid, int operation_id, const char * path_new_state, const char * path_old_state)
{
Log::message("\Handling SaveFile event\n");
// ...
}
};
SomeClass *sc = new SomeClass();
// ...
// specify a class instance in case a handler method belongs to some class
Landscape::getEventSaveFile().connect(sc->e_connections, sc, &SomeClass::event_handler);
// ...
// handler class instance is deleted with all its subscriptions removed automatically
delete sc;
//////////////////////////////////////////////////////////////////////////////
// 4. You can subscribe and unsubscribe via the handler function directly
//////////////////////////////////////////////////////////////////////////////
// subscribe to the SaveFile event with a handler function
Landscape::getEventSaveFile().connect(savefile_event_handler);
// remove subscription to the SaveFile event later by the handler function
Landscape::getEventSaveFile().disconnect(savefile_event_handler);
//////////////////////////////////////////////////////////////////////////////
// 5. Subscribe to an event saving an ID and unsubscribe later by this ID
//////////////////////////////////////////////////////////////////////////////
// define a connection ID to be used to unsubscribe later
EventConnectionId savefile_handler_id;
// subscribe to the SaveFile event with a lambda handler function and keeping connection ID
savefile_handler_id = Landscape::getEventSaveFile().connect([](const UGUID & guid, int operation_id, const char * path_new_state, const char * path_old_state) {
Log::message("\Handling SaveFile event (lambda).\n");
}
);
// remove the subscription later using the ID
Landscape::getEventSaveFile().disconnect(savefile_handler_id);
//////////////////////////////////////////////////////////////////////////////
// 6. Ignoring all SaveFile events when necessary
//////////////////////////////////////////////////////////////////////////////
// you can temporarily disable the event to perform certain actions without triggering it
Landscape::getEventSaveFile().setEnabled(false);
// ... actions to be performed
// and enable it back when necessary
Landscape::getEventSaveFile().setEnabled(true);
Return value
Event reference.Event<const UGUID &, int, const char *> getEventApplyDiff() const#
void applydiff_event_handler(const UGUID & guid, int operation_id, const char * lmap_file_path)
Usage Example
// implement the ApplyDiff event handler
void applydiff_event_handler(const UGUID & guid, int operation_id, const char * lmap_file_path)
{
Log::message("\Handling ApplyDiff event\n");
}
//////////////////////////////////////////////////////////////////////////////
// 1. Multiple subscriptions can be linked to an instance of the EventConnections
// class that you can use later to remove all these subscriptions at once
//////////////////////////////////////////////////////////////////////////////
// create an instance of the EventConnections class
EventConnections applydiff_event_connections;
// link to this instance when subscribing to an event (subscription to various events can be linked)
Landscape::getEventApplyDiff().connect(applydiff_event_connections, applydiff_event_handler);
// other subscriptions are also linked to this EventConnections instance
// (e.g. you can subscribe using lambdas)
Landscape::getEventApplyDiff().connect(applydiff_event_connections, [](const UGUID & guid, int operation_id, const char * lmap_file_path) {
Log::message("\Handling ApplyDiff event (lambda).\n");
}
);
// ...
// later all of these linked subscriptions can be removed with a single line
applydiff_event_connections.disconnectAll();
//////////////////////////////////////////////////////////////////////////////
// 2. You can subscribe and unsubscribe via an instance of the EventConnection
// class. And toggle this particular connection off and on, when necessary.
//////////////////////////////////////////////////////////////////////////////
// create an instance of the EventConnection class
EventConnection applydiff_event_connection;
// subscribe to the ApplyDiff event with a handler function keeping the connection
Landscape::getEventApplyDiff().connect(applydiff_event_connection, applydiff_event_handler);
// ...
// you can temporarily disable a particular event connection to perform certain actions
applydiff_event_connection.setEnabled(false);
// ... actions to be performed
// and enable it back when necessary
applydiff_event_connection.setEnabled(true);
// ...
// remove subscription to the ApplyDiff event via the connection
applydiff_event_connection.disconnect();
//////////////////////////////////////////////////////////////////////////////
// 3. You can add EventConnection/EventConnections instance as a member of the
// class that handles the event. In this case all linked subscriptions will be
// automatically removed when class destructor is called
//////////////////////////////////////////////////////////////////////////////
// Class handling the event
class SomeClass
{
public:
// instance of the EventConnections class as a class member
EventConnections e_connections;
// A ApplyDiff event handler implemented as a class member
void event_handler(const UGUID & guid, int operation_id, const char * lmap_file_path)
{
Log::message("\Handling ApplyDiff event\n");
// ...
}
};
SomeClass *sc = new SomeClass();
// ...
// specify a class instance in case a handler method belongs to some class
Landscape::getEventApplyDiff().connect(sc->e_connections, sc, &SomeClass::event_handler);
// ...
// handler class instance is deleted with all its subscriptions removed automatically
delete sc;
//////////////////////////////////////////////////////////////////////////////
// 4. You can subscribe and unsubscribe via the handler function directly
//////////////////////////////////////////////////////////////////////////////
// subscribe to the ApplyDiff event with a handler function
Landscape::getEventApplyDiff().connect(applydiff_event_handler);
// remove subscription to the ApplyDiff event later by the handler function
Landscape::getEventApplyDiff().disconnect(applydiff_event_handler);
//////////////////////////////////////////////////////////////////////////////
// 5. Subscribe to an event saving an ID and unsubscribe later by this ID
//////////////////////////////////////////////////////////////////////////////
// define a connection ID to be used to unsubscribe later
EventConnectionId applydiff_handler_id;
// subscribe to the ApplyDiff event with a lambda handler function and keeping connection ID
applydiff_handler_id = Landscape::getEventApplyDiff().connect([](const UGUID & guid, int operation_id, const char * lmap_file_path) {
Log::message("\Handling ApplyDiff event (lambda).\n");
}
);
// remove the subscription later using the ID
Landscape::getEventApplyDiff().disconnect(applydiff_handler_id);
//////////////////////////////////////////////////////////////////////////////
// 6. Ignoring all ApplyDiff events when necessary
//////////////////////////////////////////////////////////////////////////////
// you can temporarily disable the event to perform certain actions without triggering it
Landscape::getEventApplyDiff().setEnabled(false);
// ... actions to be performed
// and enable it back when necessary
Landscape::getEventApplyDiff().setEnabled(true);
Return value
Event reference.Event<const UGUID &, int, const Ptr<LandscapeTextures> &, const Math::ivec2 &, int> getEventTextureDraw() const#
void texturedraw_event_handler(const UGUID & guid, int operation_id, const Ptr<LandscapeTextures> & buffer, const Math::ivec2 & coords, int data_mask)
Usage Example
// implement the TextureDraw event handler
void texturedraw_event_handler(const UGUID & guid, int operation_id, const Ptr<LandscapeTextures> & buffer, const Math::ivec2 & coords, int data_mask)
{
Log::message("\Handling TextureDraw event\n");
}
//////////////////////////////////////////////////////////////////////////////
// 1. Multiple subscriptions can be linked to an instance of the EventConnections
// class that you can use later to remove all these subscriptions at once
//////////////////////////////////////////////////////////////////////////////
// create an instance of the EventConnections class
EventConnections texturedraw_event_connections;
// link to this instance when subscribing to an event (subscription to various events can be linked)
Landscape::getEventTextureDraw().connect(texturedraw_event_connections, texturedraw_event_handler);
// other subscriptions are also linked to this EventConnections instance
// (e.g. you can subscribe using lambdas)
Landscape::getEventTextureDraw().connect(texturedraw_event_connections, [](const UGUID & guid, int operation_id, const Ptr<LandscapeTextures> & buffer, const Math::ivec2 & coords, int data_mask) {
Log::message("\Handling TextureDraw event (lambda).\n");
}
);
// ...
// later all of these linked subscriptions can be removed with a single line
texturedraw_event_connections.disconnectAll();
//////////////////////////////////////////////////////////////////////////////
// 2. You can subscribe and unsubscribe via an instance of the EventConnection
// class. And toggle this particular connection off and on, when necessary.
//////////////////////////////////////////////////////////////////////////////
// create an instance of the EventConnection class
EventConnection texturedraw_event_connection;
// subscribe to the TextureDraw event with a handler function keeping the connection
Landscape::getEventTextureDraw().connect(texturedraw_event_connection, texturedraw_event_handler);
// ...
// you can temporarily disable a particular event connection to perform certain actions
texturedraw_event_connection.setEnabled(false);
// ... actions to be performed
// and enable it back when necessary
texturedraw_event_connection.setEnabled(true);
// ...
// remove subscription to the TextureDraw event via the connection
texturedraw_event_connection.disconnect();
//////////////////////////////////////////////////////////////////////////////
// 3. You can add EventConnection/EventConnections instance as a member of the
// class that handles the event. In this case all linked subscriptions will be
// automatically removed when class destructor is called
//////////////////////////////////////////////////////////////////////////////
// Class handling the event
class SomeClass
{
public:
// instance of the EventConnections class as a class member
EventConnections e_connections;
// A TextureDraw event handler implemented as a class member
void event_handler(const UGUID & guid, int operation_id, const Ptr<LandscapeTextures> & buffer, const Math::ivec2 & coords, int data_mask)
{
Log::message("\Handling TextureDraw event\n");
// ...
}
};
SomeClass *sc = new SomeClass();
// ...
// specify a class instance in case a handler method belongs to some class
Landscape::getEventTextureDraw().connect(sc->e_connections, sc, &SomeClass::event_handler);
// ...
// handler class instance is deleted with all its subscriptions removed automatically
delete sc;
//////////////////////////////////////////////////////////////////////////////
// 4. You can subscribe and unsubscribe via the handler function directly
//////////////////////////////////////////////////////////////////////////////
// subscribe to the TextureDraw event with a handler function
Landscape::getEventTextureDraw().connect(texturedraw_event_handler);
// remove subscription to the TextureDraw event later by the handler function
Landscape::getEventTextureDraw().disconnect(texturedraw_event_handler);
//////////////////////////////////////////////////////////////////////////////
// 5. Subscribe to an event saving an ID and unsubscribe later by this ID
//////////////////////////////////////////////////////////////////////////////
// define a connection ID to be used to unsubscribe later
EventConnectionId texturedraw_handler_id;
// subscribe to the TextureDraw event with a lambda handler function and keeping connection ID
texturedraw_handler_id = Landscape::getEventTextureDraw().connect([](const UGUID & guid, int operation_id, const Ptr<LandscapeTextures> & buffer, const Math::ivec2 & coords, int data_mask) {
Log::message("\Handling TextureDraw event (lambda).\n");
}
);
// remove the subscription later using the ID
Landscape::getEventTextureDraw().disconnect(texturedraw_handler_id);
//////////////////////////////////////////////////////////////////////////////
// 6. Ignoring all TextureDraw events when necessary
//////////////////////////////////////////////////////////////////////////////
// you can temporarily disable the event to perform certain actions without triggering it
Landscape::getEventTextureDraw().setEnabled(false);
// ... actions to be performed
// and enable it back when necessary
Landscape::getEventTextureDraw().setEnabled(true);
Return value
Event reference.Ptr<LandscapeTextures> getTemporaryTexture ( const Math::ivec2 & resolution ) #
Returns a fragment of terrain data as a LandscapeTextures of the specified resolution.Arguments
- const Math::ivec2 & resolution - Resolution of a temporary texture to be obtained.
Return value
LandscapeTextures instance containing a fragment of terrain data.void releaseTemporaryTexture ( const Ptr<LandscapeTextures> & texture ) #
Releases the specified temporary texture.Arguments
- const Ptr<LandscapeTextures> & texture - Temporary landscape texture to be released.
bool terrainLoad ( const Math::WorldBoundBox & bb ) #
Loads terrain data (tiles) for all landscape layer maps within the specified bounding box to cache.Arguments
- const Math::WorldBoundBox & bb - Bounding box, defining landscape layer maps for which the data is to be loaded.
Return value
true if terrain data was successfully loaded for all landscape layer maps within the specified bounding box; otherwise, false.bool render ( const Ptr<LandscapeTextures> & buffers, const Math::Mat4 & transform, Math::Scalar texel_size ) #
Renders the area of the specified landscape layer maps defined by the specified transform and texel size, to the specified buffers.Arguments
- const Ptr<LandscapeTextures> & buffers - Target texture buffers to which the specified landscape layer maps are to be rendered.
- const Math::Mat4 & transform - Transformation of the landscape terrain area to be rendered (Z-coordinate is ignored).
- Math::Scalar texel_size - Texel size to be used. Defines the size of the area depending on the buffers resolution.
Return value
true if the data of the landscape terrain area (all landscape layer maps) defined by the specified transformation and texel size, was successfully rendered to the specified buffers; otherwise, false.bool render ( const Ptr<LandscapeTextures> & buffers, const Math::Mat4 & transform, Math::Scalar texel_size, int padding ) #
Renders the area of the specified landscape layer maps defined by the specified transform and texel size, to the specified buffers. Use the padding parameter to set inner padding size for the area (when necessary).Arguments
- const Ptr<LandscapeTextures> & buffers - Target texture buffers to which the specified landscape layer maps are to be rendered.
- const Math::Mat4 & transform - Transformation of the landscape terrain area to be rendered (Z-coordinate is ignored).
- Math::Scalar texel_size - Texel size to be used. Defines the size of the area depending on the buffers resolution.
- int padding - Inner padding size for the area to be rendered (if necessary).
Return value
true if the data of the landscape terrain area (all landscape layer maps) defined by the specified transformation and texel size, was successfully rendered to the specified buffers; otherwise, false.bool render ( const Vector<Ptr<LandscapeLayerMap>> & maps, const Ptr<LandscapeTextures> & buffers, const Math::Mat4 & transform, Math::Scalar texel_size ) #
Renders the area of the specified landscape layer maps defined by the specified transform and texel size, to the specified buffers.Arguments
- const Vector<Ptr<LandscapeLayerMap>> & maps - List of the landscape layer maps to be rendered.
- const Ptr<LandscapeTextures> & buffers - Target texture buffers to which the specified landscape layer maps are to be rendered.
- const Math::Mat4 & transform - Transformation of the landscape terrain area to be rendered (Z-coordinate is ignored).
- Math::Scalar texel_size - Texel size to be used. Defines the size of the area depending on the buffers resolution.
Return value
true if the data of the landscape terrain area (specified landscape layer maps) defined by the specified transformation and texel size, was successfully rendered to the specified buffers; otherwise, false.bool render ( const Vector<Ptr<LandscapeLayerMap>> & maps, const Ptr<LandscapeTextures> & buffers, const Math::Mat4 & transform, Math::Scalar texel_size, int padding ) #
Renders the area of the specified landscape layer maps defined by the specified transform and texel size, to the specified buffers. Use the padding parameter to set inner padding size for the area (when necessary).Arguments
- const Vector<Ptr<LandscapeLayerMap>> & maps - List of the landscape layer maps to be rendered.
- const Ptr<LandscapeTextures> & buffers - Target texture buffers to which the specified landscape layer maps are to be rendered.
- const Math::Mat4 & transform - Transformation of the landscape terrain area to be rendered (Z-coordinate is ignored).
- Math::Scalar texel_size - Texel size to be used. Defines the size of the area depending on the buffers resolution.
- int padding - Inner padding size for the area to be rendered.
Return value
true if the data of the landscape terrain area (specified landscape layer maps) defined by the specified transformation and texel size, was successfully rendered to the specified buffers; otherwise, false.void asyncTextureDraw ( int operation_id, const UGUID & file_guid, const Math::ivec2 & coord, const Math::ivec2 & resolution, int flags_file_data, const Vector< Math::WorldBoundBox> & bounds_preload ) #
Commences an asynchronous GPU-based drawing operation with forced pre-loading of terrain data within the specified bounding box (all landscape layer maps). The drawing operation represents modification of the texture buffer of the specified size taken at specified coordinates and combining data layers defined by the specified flags. The operation itself is to be implemented in the TextureDraw event handler. This method can be used for implementing GPU-based terrain modification (e.g. brushes) that requires additional data beyond the area specified by coords and resolution parameters as well as the data of other landscape layer maps (e.g. a copy brush).Arguments
- int operation_id - Draw operation ID.
- const UGUID & file_guid - GUID of the landscape layer map file to be modified.
- const Math::ivec2 & coord - Coordinates of the upper left corner of the landscape layer map data segment to be modified along the X and Y axes.
- const Math::ivec2 & resolution - Resolution of the landscape layer map data segment to be modified along the X and Y axes.
- int flags_file_data - Data layer mask. A combination of FLAGS_FILE_DATA_* flags indicating data layers to be affected (heights, albedo, certain masks).
- const Vector< Math::WorldBoundBox> & bounds_preload - Bounding box (world) specifying the area containing terrain tiles (all landscape layer maps) to be loaded to memory prior to making modifications.
void asyncTextureDraw ( int operation_id, const UGUID & file_guid, const Math::ivec2 & coord, const Math::ivec2 & resolution, int flags_file_data ) #
Commences an asynchronous GPU-based drawing operation. The drawing operation represents modification of the texture buffer of the specified size taken at specified coordinates and combining data layers defined by the specified flags. The operation itself is to be implemented in the TextureDraw event handler. This method can be used for implementing GPU-based terrain modification (e.g. brushes).Arguments
- int operation_id - Draw operation ID.
- const UGUID & file_guid - GUID of the landscape layer map file to be modified.
- const Math::ivec2 & coord - Coordinates of the upper left corner of the landscape layer map data segment to be modified along the X and Y axes.
- const Math::ivec2 & resolution - Resolution of the landscape layer map data segment to be modified along the X and Y axes.
- int flags_file_data - Data layer mask. A combination of FLAGS_FILE_DATA_* flags indicating data layers to be affected (heights, albedo, certain masks).
void asyncTextureDraw ( int operation_id, const UGUID & file_guid, const Math::ivec2 & coord, const Math::ivec2 & resolution ) #
Commences an asynchronous GPU-based drawing operation. The drawing operation represents modification of the texture buffer of the specified size taken at specified coordinates and combining all data layers. The operation itself is to be implemented in the TextureDraw event handler. This method can be used for implementing GPU-based terrain modification (e.g. brushes).Arguments
- int operation_id - Draw operation ID.
- const UGUID & file_guid - GUID of the landscape layer map file to be modified.
- const Math::ivec2 & coord - Coordinates of the upper left corner of the landscape layer map data segment to be modified along the X and Y axes.
- const Math::ivec2 & resolution - Resolution of the landscape layer map data segment to be modified along the X and Y axes.
void asyncTextureDraw ( const UGUID & file_guid, const Math::ivec2 & coord, const Math::ivec2 & resolution, int flags_file_data, const Vector< Math::WorldBoundBox> & bounds_preload ) #
Commences an asynchronous GPU-based drawing operation with forced pre-loading of terrain data within the specified bounding box (all landscape layer maps). The drawing operation represents modification of the texture buffer of the specified size taken at specified coordinates and combining data layers defined by the specified flags. The operation itself is to be implemented in the TextureDraw event handler. This method can be used for implementing GPU-based terrain modification (e.g. brushes) that requires additional data beyond the area specified by coords and resolution parameters as well as the data of other landscape layer maps (e.g. a copy brush).Arguments
- const UGUID & file_guid - GUIGUID of the landscape layer map file to be modified.
- const Math::ivec2 & coord - Coordinates of the upper left corner of the landscape layer map data segment to be modified along the X and Y axes.
- const Math::ivec2 & resolution - Resolution of the landscape layer map data segment to be modified along the X and Y axes.
- int flags_file_data - Data layer mask. A combination of FLAGS_FILE_DATA_* flags indicating data layers to be affected (heights, albedo, certain masks).
- const Vector< Math::WorldBoundBox> & bounds_preload - Bounding box (world) specifying the area containing terrain tiles (all landscape layer maps) to be loaded to memory prior to making modifications.
void asyncTextureDraw ( const UGUID & file_guid, const Math::ivec2 & coord, const Math::ivec2 & resolution, int flags_file_data ) #
Commences an asynchronous GPU-based drawing operation. The drawing operation represents modification of the texture buffer of the specified size taken at specified coordinates and combining data layers defined by the specified flags. The operation itself is to be implemented in the TextureDraw event handler. This method can be used for implementing GPU-based terrain modification (e.g. brushes).Arguments
- const UGUID & file_guid - GUID of the landscape layer map file to be modified.
- const Math::ivec2 & coord - Coordinates of the upper left corner of the landscape layer map data segment to be modified along the X and Y axes.
- const Math::ivec2 & resolution - Resolution of the landscape layer map data segment to be modified along the X and Y axes.
- int flags_file_data - Data layer mask. A combination of FLAGS_FILE_DATA_* flags indicating data layers to be affected (heights, albedo, certain masks).
void asyncTextureDraw ( const UGUID & file_guid, const Math::ivec2 & coord, const Math::ivec2 & resolution ) #
Commences an asynchronous GPU-based drawing operation. The drawing operation represents modification of the texture buffer of the specified size taken at specified coordinates and combining all data layers. The operation itself is to be implemented in the TextureDraw event handler. This method can be used for implementing GPU-based terrain modification (e.g. brushes).Arguments
- const UGUID & file_guid - GUID of the landscape layer map file to be modified.
- const Math::ivec2 & coord - Coordinates of the upper left corner of the landscape layer map data segment to be modified along the X and Y axes.
- const Math::ivec2 & resolution - Resolution of the landscape layer map data segment to be modified along the X and Y axes.
void asyncApplyDiff ( int operation_id, const UGUID & file_guid, const char * path ) #
Applies the state of the landscape layer map stored in the specified file to the landscape layer map file with the specified GUID.Arguments
- int operation_id - Operation ID.
- const UGUID & file_guid - GUID of the landscape layer map file to which a state stored at the specified path is to be applied.
- const char * path - Path to a file where the current landscape map modification state is stored.
void asyncApplyDiff ( const UGUID & file_guid, const char * path ) #
Applies the state of the landscape layer map stored in the specified file to the landscape layer map file with the specified GUID.Arguments
- const UGUID & file_guid - GUID of the landscape layer map file to which a state stored at the specified path is to be applied.
- const char * path - Path to a file where the current landscape map modification state is stored.
void asyncSaveFile ( int operation_id, const UGUID & file_guid ) #
Saves the landscape layer map file with the specified GUID.Arguments
- int operation_id - Operation ID.
- const UGUID & file_guid - GUID of the landscape layer map file.
void asyncSaveFile ( const UGUID & file_guid ) #
Saves the landscape layer map file with the specified GUID.Arguments
void asyncSaveFile ( int operation_id, const UGUID & file_guid, const char * path_new_diff, const char * path_old_diff ) #
Saves the specified landscape layer map file applying all changes along with saving old and new states (diff) to temporary files. These temporary files can be used to perform undo/redo operations via the applyDiff() method.Arguments
- int operation_id - Operation ID.
- const UGUID & file_guid - GUID of the landscape layer map file.
- const char * path_new_diff - Path to a file to store the new landscape layer map state.
- const char * path_old_diff - Path to a file to store the old landscape layer map state.
void asyncSaveFile ( const UGUID & file_guid, const char * path_new_diff, const char * path_old_diff ) #
Saves the specified landscape layer map file applying all changes along with saving old and new states (diff) to temporary files. These temporary files can be used to perform undo/redo operations via the applyDiff() method.UGUID lmap_file_guid; // .lmap file GUID
String cache_path; // path to some cache directory
String new_filepath; // path to store a new state
String old_filepath; // path to store an old state
// method implementing the "apply" operation
void apply() override
{
// generating necessary paths to save states (generate_filepath - some abstract method)
new_filepath = generate_filepath(cache_path);
old_filepath_ = generate_filepath(cache_path);
// applying changes and saving current and previous states
Landscape::asyncSaveFile(lmap_file_guid, new_filepath, old_filepath);
}
// method implementing the "undo" operation by applying the previous saved state
void undo() override
{
if (!old_filepath.empty())
Landscape::asyncApplyDiff(lmap_file_guid, old_filepath);
}
// method implementing the "redo" operation by applying the new saved state
void redo() override
{
if (!new_filepath.empty())
Landscape::asyncApplyDiff(lmap_file_guid, new_filepath);
}
Arguments
- const UGUID & file_guid - GUID of the landscape layer map file.
- const char * path_new_diff - Path to a file to store the new landscape layer map state.
- const char * path_old_diff - Path to a file to store the old landscape layer map state.
void filesClose ( const Vector<UGUID> & reload_files ) #
Closes .lmap files for all landscape layer maps and reloads the ones with specified GUIDs. This method should be called before making any changes (modification, deletion, renaming) to .lmap files of the landscape terrain object to avoid conflicts, as these files are streamed continuosly by the Engine. Thus, by calling this method you inform the Engine that it should stop streaming terrain data. The list informs the Engine which files are no longer valid and should be reloaded or removed. As you're done with modification you should call the filesOpen() method to resume streaming operations.Arguments
- const Vector<UGUID> & reload_files - List of GUIDs of .lmap files to be reloaded. This list should contain .lmap files, that were deleted or having their data changed (albedo, heights, masks). If there are no such files, you can simply call the filesClose() method.
void filesClose ( ) #
Closes .lmap files for all landscape layer maps.This method should be called before making any changes (modification, deletion, renaming) to .lmap files of the landscape terrain object to avoid conflicts, as these files are streamed continuosly by the Engine. Thus, by calling this method you inform the Engine that it should stop streaming terrain data. As you're done with modification you should call the filesOpen() method to resume streaming operations.void filesOpen ( ) #
Opens .lmap files for all landscape layer maps.This method should be called after making any changes (modification, deletion, renaming) to .lmap files of the landscape terrain object. Prior to making such modifications the filesClose() method should be called.Ptr<ObjectLandscapeTerrain> getActiveTerrain ( ) #
Returns the current active Landscape Terrain object.Return value
Landscape Terrain object that is currently active.int generateOperationID ( ) #
Generates a new ID for the operation. This ID is used to manage operations.int id = Landscape::generateOperationID();
// user's code (bounding to ID)
Landscape::asyncTextureDraw(id, file_guid, coord, resolution, flags_file_data);