Landscape Class
This class is used to manage landscape terrain rendering and modification.
Terrain modification is performed in asynchronous mode either on CPU or 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 impemented inside a callback handler.
CPU-Based Terrain Modification#
The workflow is as follows:
- Implement your CPU-based terrain modification logic in a function:
- Set this callback function to be fired when an Image Draw (CPU-based terrain modification) operation is performed by calling the addImageDrawCallback() method.
- Commence a CPU drawing operation by calling the asyncImageDraw() 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.
// CPU-based modification handler
void my_image_draw(UGUID guid, int id, LandscapeImagesPtr buffer, ivec2 coord, int data_mask)
{
// getting a pointer to the buffer's albedo image
ImagePtr img_a = buffer->getAlbedo();
// loading a new image to modify albedo, and setting its size and format
img_a->load("albedo_brush.jpg");
img_a->resize(64, 64);
img_a->convertToFormat(Image::FORMAT_RGBA8);
// getting a pointer to the buffer's height map
ImagePtr img = buffer->getHeight();
// loading a new image to modify heights, and setting its size and format
img->load("hbrush.png");
img->resize(64, 64);
img->convertToFormat(Image::FORMAT_R32F);
}
// ...
virtual int AppWorldLogic::init()
{
// adding a callback to be fired on an Image Draw operation
Landscape::addImageDrawCallback(MakeCallback(my_image_draw));
// getting an existing landscape terrain object named "MyTerrain" from the world
ObjectLandscapeTerrainPtr terrain = checked_ptr_cast<ObjectLandscapeTerrain>(World::getNodeByName("MyTerrain"));
// getting the first layermap that we're going to modify
LandscapeLayerMapPtr lmap = checked_ptr_cast<LandscapeLayerMap>(terrain->getChild(0));
// commencing an Image Draw operation for the selected landscape map at (15, 15) with the size of [64 x 64]
Landscape::asyncImageDraw(lmap->getGUID(), ivec2(15,15), ivec2(64, 64), ~0);
return 1;
}
// ...
virtual int shutdown()
{
// clearing callbacks
Landscape::clearImageDrawCallbacks();
return 1;
}
The process is as follows:
- 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 (either LandscapeImages) of the specified resolution.
- Upon completion of the copying process a callback function set via the addImageDrawCallback() method is called. This function modifies the buffer.
- After this selected data layers of the modified buffer are pasted back to the landscape layer map file.
GPU-Based Terrain Modification#
The workflow and the process are similar to the one described above for CPU-based modification:
- Implement your GPU-based terrain modification logic in a function.
- Set this callback function to be fired when a Texture Draw (GPU-based terrain modification) operation is performed by calling the addTextureDrawCallback() method.
- Commence a CPU or 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(UGUID guid, int id, LandscapeTexturesPtr buffer, ivec2 coord, int data_mask)
{
// getting a built-in "cirle_soft" Editor's brush
MaterialPtr mat = Materials::findMaterial("circle_soft");
if (mat) {
// setting necessary textures (e.g., albedo and heights)
mat->setTexture("terrain_albedo", buffer->getAlbedo());
mat->setTexture("terrain_height", buffer->getHeight());
// setting up brush material parameters (size, color, etc. and specifying masks to be affected by the brush)
mat->setParameterFloat("size", 100.0f);
mat->setParameterFloat("height", 10.0f);
mat->setParameterFloat4("color", vec4::RED);
mat->setParameterInt("data_mask", Landscape::FLAGS_DATA_ALBEDO | Landscape::FLAGS_DATA_HEIGHT);
// running material's "brush" expression
mat->runExpression("brush", buffer->getResolution().x, buffer->getResolution().y);
// resetting material textures
mat->setTexture("terrain_albedo", nullptr);
mat->setTexture("terrain_height", nullptr);
}
}
// ...
virtual int AppWorldLogic::init()
{
// adding a callback to be fired on a Texture Draw operation
Landscape::addTextureDrawCallback(MakeCallback(my_texture_draw));
// getting an existing landscape terrain object named "MyTerrain" from the world
ObjectLandscapeTerrainPtr terrain = checked_ptr_cast<ObjectLandscapeTerrain>(World::getNodeByName("MyTerrain"));
// getting the first layermap that we're going to modify
LandscapeLayerMapPtr lmap = checked_ptr_cast<LandscapeLayerMap>(terrain->getChild(0));
// commencing a Texture Draw operation for the selected landscape map at (1, 1) with the size of [32 x 32]
Landscape::asyncTextureDraw(lmap->getGUID(), ivec2(1, 1), ivec2(32, 32), ~0);
return 1;
}
// ...
virtual int shutdown()
{
// clearing callbacks
Landscape::clearTextureDrawCallbacks();
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 callback function set via the addTextureDrawCallback() method is called. This function modifies the buffer.
- After this selected data layers of the modified buffer are pasted back to the landscape layer map file.
Landscape Class
Members
LandscapeTextures getTemporaryTexture ( ivec2 resolution ) #
Returns a fragment of terrain data as a LandscapeTextures of the specified resolution.Arguments
- ivec2 resolution - Resolution of a temporary texture to be obtained.
Return value
LandscapeTextures instance containing a fragment of terrain data.void releaseTemporaryTexture ( LandscapeTextures texture ) #
Releases the specified temporary texture.Arguments
- LandscapeTextures texture - Temporary landscape texture to be released.
int terrainLoad ( WorldBoundBox bb ) #
Loads terrain data (tiles) for all landscape layer maps within the specified bounding box to cache.Arguments
- WorldBoundBox bb - Bounding box, defining landscape layer maps for which the data is to be loaded.
Return value
1 if terrain data was successfully loaded for all landscape layer maps within the specified bounding box; otherwise, 0.int asyncImageDraw ( UGUID guid, ivec2 coord, ivec2 resolution, int flags_file_data ) #
Commences an asynchronous CPU-based drawing operation. The drawing operation represents modification of the image 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 ImageDrawCallback handler. This method can be used for implementing CPU-based terrain modification (e.g. brushes).Arguments
- UGUID guid - GUID of the landscape layer map file to be modified.
- ivec2 coord - Coordinates of the upper left corner of the landscape layer map data segment to be modified along the X and Y axes.
- ivec2 resolution - Resolution of the landscape layer map data segment to be modified along the X and Y axes.
- int flags_file_data - FlagsData layer flags. A combination of FLAGS_FILE_DATA_* flags indicating data layers to be affected (heights, albedo, certain masks).
Return value
Draw operation IDint asyncImageDraw ( UGUID guid, ivec2 coord, ivec2 resolution ) #
Commences an asynchronous CPU-based drawing operation. The drawing operation represents modification of the image buffer of the specified size taken at specified coordinates and combining all data layers. The operation itself is to be implemented in the ImageDrawCallback handler. This method can be used for implementing CPU-based terrain modification (e.g. brushes).Arguments
- UGUID guid - GUID of the landscape layer map file to be modified.
- ivec2 coord - Coordinates of the upper left corner of the landscape layer map data segment to be modified along the X and Y axes.
- ivec2 resolution - Resolution of the landscape layer map data segment to be modified along the X and Y axes.
Return value
Draw operation IDint asyncApplyDiff ( UGUID guid, string 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
- UGUID guid - GUID of the landscape layer map file to which a state stored at the specified path is to be applied.
- string path - Path to a file where the current landscape map modification state is stored.
Return value
1 if the state of the landscape layer map stored in the specified file was successfully applied; otherwise, 0.int asyncSaveFile ( UGUID file_guid ) #
Saves the landscape layer map file with the specified GUID.Arguments
- UGUID file_guid - GUID of the landscape layer map file.
Return value
1 if the landscape layer map file was successfully saved applying all changes along with saving old and new states (diff) to temporary files; otherwise, 0.int asyncSaveFile ( UGUID guid, string path_new_state, string path_old_state ) #
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
- UGUID guid - GUID of the landscape layer map file.
- string path_new_state - Path to a file to store the new landscape layer map state.
- string path_old_state - Path to a file to store the old landscape layer map state.