Jump to content

create landscape in editor plugin


photo

Recommended Posts

Hi All,

A few months ago I started working with Unigine. Before that I used Unity3d. I am very enthusiastic about Unigine. To get to know Unigine I am working on an editor plugin to create heightmaps and terrain bitmaps from real world data. I'm using the REST api from Bing maps for the elevations and terrain bitmaps. No problems so far. The following images give an impression of the plugin.

ui.thumb.jpg.0394e4767a2ce6583286e34ece76d24f.jpg

Heightmap, terrain bitmap and 3d landscape

heightmap.jpg.f3fcb7dd25a738244083204dc99061c1.jpg          terrainmap.jpg.ef8c26ca970b570fa1a3f6177f328229.jpg         landscape.jpg.ad5e79215b4328fb14ad85bf64fb881f.jpg 

Now I want to create a terrain and layermap based on this data. The code is based on "Working with Landscape Terrain via Code" in the documentation. I get the following errors: test.lmap not found/load and no landscape asset has been created.

error.jpg.97aa1d7198ff09ddb37727c90997079b.jpg

I have tried several modifications in the code but nothing worked.
Does anyone have an idea?

 

 

 

 

 

  • Like 1
Link to comment

Hi Silent,

Since the change didn't work, I went to see where else a setpath occurs. Then it turned out that change of

lmapCreator-> setPath (String :: format ("% s.lmap", lmapName.get ()));

in

lmapCreator-> setPath (FileSystem :: addVirtualFile (String :: format ("% s.lmap", lmapName.get ())));

the solution is.
I still have to figure out why the heightmap and albedo map are not loaded.

Thank you for the assistance.

 

Link to comment

 

Hi Silent,

When the test function is run for the first time you will get the reported error message. However, a test.lmap is created in the project's data directory. If we close the project (without save world) and start it again, we see test.lmap in the asset browser and the file can be found if we run the test function again.

Link to comment

So, here is the our variant of your code:

Spoiler

// function creating the Landscape Terrain object using the generated .lmap file
void createTerrain(const Unigine::UGUID &guid)
{
	using namespace Unigine;
	// create new terrain
	ObjectLandscapeTerrainPtr terrain = ObjectLandscapeTerrain::create();
	terrain->setActiveTerrain(true);
	terrain->setCollision(true, 0);
	terrain->setName("TestTerrain");
	terrain->setSaveToWorldEnabledRecursive(true);
	terrain->setShowInEditorEnabledRecursive(true);

	// create layer map based on created .lmap file
	LandscapeLayerMapPtr lmap = LandscapeLayerMap::create();
	lmap->setParent(Landscape::getActiveTerrain());
	lmap->setPath(guid.getFileSystemString());
	lmap->setName("test");
	lmap->setSize({1024, 1024});
	lmap->setHeightScale(1.0);
	lmap->setSaveToWorldEnabledRecursive(true);
	lmap->setShowInEditorEnabledRecursive(true);
}

QString createEmptyLandscapeMap(const QString &path,
		const QString &desired_name)
{
	QString name = desired_name;
	if (name.isEmpty())
		name = qsl("landscape.lmap");

	name = fs::makeUniqueFilename(name,
			[&path](const QString &unique_name) -> bool {
				return !fs::fileExists(fs::appendPath(path, unique_name));
			});

	QString filepath = fs::appendPath(path, name);
	auto creator = LandscapeMapFileCreator::create();
	creator->setPath(filepath.toCChar());

	as::LandscapeMapImportParams params;
	ivec2 resolution(params.resolution_x, params.resolution_y);
	ivec2 grid;
	ivec2 tilesize = calcOptimalTilesize(grid, resolution);

	creator->setResolution(resolution);
	creator->setGrid(grid);

	auto processor = [tilesize](LandscapeMapFileCreatorPtr, LandscapeImagesPtr images, int, int ) {
		fillEmptyLanscapeMap(images, tilesize);
	};

	auto callback = MakeCallback(&processor, &decltype(processor)::operator());
	creator->addCreateCallback(callback);

	creator->run(false, false);

	return filepath;
}

void fillEmptyLanscapeMap(const LandscapeImagesPtr &images, const Math::ivec2 &tilesize)
{
	// Heightmap
	ImagePtr heightmap = images->getHeight();
	if (!heightmap->create2D(tilesize.x, tilesize.y, Image::FORMAT_R32F))
		return;

	size_t size = heightmap->getWidth() * heightmap->getHeight();
	float *p = reinterpret_cast<float *>(heightmap->getPixels2D());
	for (size_t i = 0; i < size; ++i)
		p[i] = 0.0f;

	// Heightmap Opacity
	ImagePtr opacity = images->getOpacityHeight();
	if (!opacity->create2D(tilesize.x, tilesize.y, Image::FORMAT_R32F))
		return;

	size = opacity->getWidth() * opacity->getHeight();
	p = reinterpret_cast<float *>(opacity->getPixels2D());
	for (size_t i = 0; i < size; ++i)
		p[i] = 1.0f;

	// Albedo With Opacity
	ImagePtr albedo = images->getAlbedo();
	if (!albedo->create2D(tilesize.x, tilesize.y, Image::FORMAT_RGBA8))
		return;

	size = albedo->getWidth() * albedo->getHeight() * albedo->getNumChannels();
	unsigned char *puc = reinterpret_cast<unsigned char *>(albedo->getPixels2D());
	for (size_t i = 0; i < size; ++i)
		puc[i] = 255;
}

void test()
{
	QString path = terrain::createEmptyLandscapeMap("/home/danvern/source/engine/data");
	createTerrain(Unigine::FileSystem::getGUID(TOCHAR(path)));
}

 

No errors or whatsoever. Can you please provide us a minimal reproduction code for your behavior?

Thanks!

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment

Please, check the modified sources in attachment. There were couple of issues with specific filesystem work under the Windows (no errors or whatsoever were on Linux).

We will see how we can improve this behavior in the future releases, so no additional code is required to do such task.

Thanks for the test scene!

TerrainPlugin.zip

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment
×
×
  • Create New...