Heightmap editor + saving
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <OgreTerrainPagedWorldSection.h>
|
||||
#include <OgrePage.h>
|
||||
#include <OgreTerrainPaging.h>
|
||||
#include <OgreFileSystemLayer.h>
|
||||
|
||||
#include "GameData.h"
|
||||
#include "Components.h"
|
||||
@@ -71,11 +72,50 @@ struct HeightData {
|
||||
}
|
||||
return img_brushes.getColourAt(x, y + m, 0).r;
|
||||
}
|
||||
float get_base_height(const Ogre::Vector2 &worldOffset, int x, int y)
|
||||
float get_world_x(int x)
|
||||
{
|
||||
return (float)(x - (int)img.getWidth() / 2) * BRUSH_SIZE;
|
||||
}
|
||||
float get_world_y(int y)
|
||||
{
|
||||
return (float)(y - (int)img.getHeight() / 2) * BRUSH_SIZE;
|
||||
}
|
||||
int get_img_x(float world_x)
|
||||
{
|
||||
float world_img_x = world_x + img.getWidth() * BRUSH_SIZE / 2;
|
||||
int ret = world_img_x / BRUSH_SIZE;
|
||||
// ret = Ogre::Math::Clamp(ret, 0, (int)img.getWidth() - 1);
|
||||
return ret;
|
||||
}
|
||||
int get_img_y(float world_z)
|
||||
{
|
||||
float world_img_y = world_z + img.getHeight() * BRUSH_SIZE / 2;
|
||||
int ret = world_img_y / BRUSH_SIZE;
|
||||
// ret = Ogre::Math::Clamp(ret, 0, (int)img.getHeight() - 1);
|
||||
return ret;
|
||||
}
|
||||
void update_heightmap(const Ogre::Image &heightmap)
|
||||
{
|
||||
img = heightmap;
|
||||
}
|
||||
void save_heightmap()
|
||||
{
|
||||
Ogre::String group =
|
||||
Ogre::ResourceGroupManager::getSingleton()
|
||||
.findGroupContainingResource("world_map.png");
|
||||
Ogre::FileInfoListPtr fileInfoList(
|
||||
Ogre::ResourceGroupManager::getSingleton()
|
||||
.findResourceFileInfo(group, "world_map.png"));
|
||||
OgreAssert(fileInfoList->size() == 1,
|
||||
"worpd_map.png should be there and only once");
|
||||
Ogre::String path = fileInfoList->at(0).archive->getName() +
|
||||
"/" + "world_map.png";
|
||||
Ogre::FileSystemLayer::removeFile(path);
|
||||
img.save(path);
|
||||
}
|
||||
float get_base_height(long world_x, long world_y)
|
||||
{
|
||||
float height = 0.0f;
|
||||
int world_x = worldOffset.x + x;
|
||||
int world_y = worldOffset.y + y;
|
||||
int world_img_x =
|
||||
world_x + (int)img.getWidth() * BRUSH_SIZE / 2;
|
||||
int world_img_y =
|
||||
@@ -91,7 +131,7 @@ struct HeightData {
|
||||
world_img_x >= img.getWidth() * BRUSH_SIZE ||
|
||||
world_img_y < 0 ||
|
||||
world_img_y >= img.getWidth() * BRUSH_SIZE) {
|
||||
height = -1.0f;
|
||||
height = 0.0f;
|
||||
goto out;
|
||||
}
|
||||
color = img.getColourAt(map_img_x, map_img_y, 0);
|
||||
@@ -103,7 +143,7 @@ struct HeightData {
|
||||
out:
|
||||
return height;
|
||||
}
|
||||
float get_noise_height(const Ogre::Vector2 &worldOffset, int x, int y)
|
||||
float get_noise_height(long world_x, long world_y)
|
||||
{
|
||||
int h;
|
||||
Ogre::Vector2 noisePoint;
|
||||
@@ -122,7 +162,7 @@ out:
|
||||
for (h = 0; h < (int)sizeof(noise_values) /
|
||||
(int)sizeof(noise_values[0]);
|
||||
h++) {
|
||||
noisePoint = (worldOffset + Ogre::Vector2(x, y) +
|
||||
noisePoint = (Ogre::Vector2(world_x, world_y) +
|
||||
noise_pass[h].noiseOfft) *
|
||||
noise_pass[h].noiseMul;
|
||||
int noise_x =
|
||||
@@ -139,31 +179,44 @@ out:
|
||||
}
|
||||
return noise_values[0] + noise_values[1];
|
||||
}
|
||||
float get_height(Ogre::TerrainGroup *terrainGroup, long x, long y,
|
||||
int j, int i)
|
||||
float get_height(Ogre::TerrainGroup *terrainGroup, long world_x,
|
||||
long world_y)
|
||||
{
|
||||
uint16_t terrainSize = terrainGroup->getTerrainSize();
|
||||
Ogre::Vector2 worldOffset(Ogre::Real(x * (terrainSize - 1)),
|
||||
Ogre::Real(y * (terrainSize - 1)));
|
||||
float brush_height0 =
|
||||
HeightData::get_singleton()->get_brush_height(
|
||||
0, j % BRUSH_SIZE, i % BRUSH_SIZE) -
|
||||
0.55f;
|
||||
float brush_height1 =
|
||||
HeightData::get_singleton()->get_brush_height(
|
||||
1, j % BRUSH_SIZE, i % BRUSH_SIZE) -
|
||||
0.55f;
|
||||
long grid_center_x = img.getWidth() * BRUSH_SIZE / 2;
|
||||
long grid_center_y = img.getHeight() * BRUSH_SIZE / 2;
|
||||
long world_grid_x = world_x + grid_center_x;
|
||||
long world_grid_y = world_y + grid_center_y;
|
||||
float amplitude = 150.0f;
|
||||
if (world_grid_x < 0 || world_grid_y < 0) {
|
||||
std::cout << "world: " << world_x << " " << world_y
|
||||
<< " ";
|
||||
std::cout << "grid: " << world_grid_x << " ";
|
||||
std::cout << world_grid_y << std::endl;
|
||||
return -amplitude;
|
||||
}
|
||||
OgreAssert(world_grid_x >= 0, "bad world x");
|
||||
OgreAssert(world_grid_y >= 0, "bad world y");
|
||||
long cell = 8;
|
||||
long b1 = (world_grid_x / cell) * cell + cell / 2;
|
||||
long b2 = (world_grid_y / cell) * cell + cell / 2;
|
||||
long o1 = Ogre::Math::Abs(world_grid_x - b1);
|
||||
long o2 = Ogre::Math::Abs(world_grid_y - b2);
|
||||
// std::cout << "h: " << o1 << " " << o2 << std::endl;
|
||||
// std::cout << "h: " << (o1 * o1 + o2 * o2) << std::endl;
|
||||
float hbase = 1.0 / (1.0f + 0.02f * (o1 * o1 + o2 * o2));
|
||||
float h1 = hbase * 0.5f + 0.5f;
|
||||
float h2 = (1.0f - hbase) * 0.5f;
|
||||
float mheight =
|
||||
Ogre::Math::lerp(
|
||||
brush_height1, brush_height0,
|
||||
HeightData::get_singleton()->get_base_height(
|
||||
worldOffset, j, i)) *
|
||||
120.0f;
|
||||
(Ogre::Math::lerp(h2, h1,
|
||||
get_base_height(world_x, world_y)) -
|
||||
0.51f) *
|
||||
amplitude;
|
||||
float height = mheight;
|
||||
if (mheight > 0.5f)
|
||||
height += 2.0f + get_noise_height(worldOffset, j, i);
|
||||
height += 2.0f + get_noise_height(world_x, world_y);
|
||||
else if (mheight < -0.5f)
|
||||
height -= 2.0f + get_noise_height(worldOffset, j, i);
|
||||
height -= 2.0f + get_noise_height(world_x, world_y);
|
||||
// OgreAssert(false, "height");
|
||||
return height;
|
||||
}
|
||||
};
|
||||
@@ -231,11 +284,29 @@ public:
|
||||
// Ogre::Vector2(img.getWidth(), img.getHeight()) * 0.5f;
|
||||
float chunk = 128.0f;
|
||||
Ogre::Vector2 revisedValuePoint;
|
||||
Ogre::Vector3 worldPos;
|
||||
terrainGroup->convertTerrainSlotToWorldPosition(x, y,
|
||||
&worldPos);
|
||||
for (int i = 0; i < terrainSize; i++)
|
||||
for (int j = 0; j < terrainSize; j++) {
|
||||
float height =
|
||||
HeightData::get_singleton()->get_height(
|
||||
terrainGroup, x, y, j, i);
|
||||
long world_x = (long)(worldPos.x + j -
|
||||
(terrainSize - 1) / 2);
|
||||
long world_y = (long)(worldPos.z + i -
|
||||
(terrainSize - 1) / 2);
|
||||
float height = 0.0f;
|
||||
int k, l;
|
||||
for (l = -1; l < 2; l++)
|
||||
for (k = -1; k < 2; k++) {
|
||||
height +=
|
||||
HeightData::get_singleton()
|
||||
->get_height(
|
||||
terrainGroup,
|
||||
world_x +
|
||||
4 * k,
|
||||
world_y +
|
||||
4 * l);
|
||||
}
|
||||
height /= 9.0f;
|
||||
|
||||
// height = -2.0f;
|
||||
heightMap[i * terrainSize + j] = height;
|
||||
@@ -526,16 +597,16 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
priv.mSunUpdate.reset();
|
||||
}
|
||||
});
|
||||
ecs.system<const CharacterBase, const Terrain>("UpdateTerrainStatus")
|
||||
ecs.system<const ECS::Camera, const Terrain>("UpdateTerrainStatus")
|
||||
.kind(flecs::OnUpdate)
|
||||
.without<TerrainReady>()
|
||||
.each([](const CharacterBase &ch, const Terrain &terrain) {
|
||||
.each([](const ECS::Camera &cam, const Terrain &terrain) {
|
||||
std::cout << "mTerrainReady: " << terrain.mTerrainReady
|
||||
<< "\n";
|
||||
std::cout << "mBodyNode: " << ch.mBodyNode << "\n";
|
||||
if (ch.mBodyNode && terrain.mTerrainReady) {
|
||||
if (cam.mCameraNode && terrain.mTerrainReady) {
|
||||
long x, y;
|
||||
Ogre::Vector3 pos = ch.mBodyNode->getPosition();
|
||||
Ogre::Vector3 pos =
|
||||
cam.mCameraNode->getPosition();
|
||||
terrain.mTerrainGroup
|
||||
->convertWorldPositionToTerrainSlot(
|
||||
pos, &x, &y);
|
||||
@@ -560,8 +631,7 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
item.position = Ogre::Vector3(0, 0, 0);
|
||||
float height =
|
||||
HeightData::get_singleton()->get_height(
|
||||
terrain.mTerrainGroup, 0, 0, 0,
|
||||
0);
|
||||
terrain.mTerrainGroup, 0, 0);
|
||||
item.position.y = height;
|
||||
placement.altar_items.push_back(item);
|
||||
for (i = -64000; i < 64000; i += 2000)
|
||||
@@ -586,14 +656,10 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
HeightData::get_singleton()
|
||||
->get_height(
|
||||
terrain.mTerrainGroup,
|
||||
xslot,
|
||||
yslot,
|
||||
(int)offset.x +
|
||||
(terrainSize -
|
||||
1) / 2,
|
||||
(int)offset.z +
|
||||
(terrainSize -
|
||||
1) / 2);
|
||||
(long)position
|
||||
.x,
|
||||
(long)position
|
||||
.z);
|
||||
#if 0
|
||||
height =
|
||||
terrain.mTerrainGroup
|
||||
@@ -672,8 +738,31 @@ float TerrainModule::get_height(Ogre::TerrainGroup *group,
|
||||
group->convertTerrainSlotToWorldPosition(xslot, yslot, &slotpos);
|
||||
Ogre::Vector3 offset = (position - slotpos) * terrainSize / worldSize;
|
||||
float height = HeightData::get_singleton()->get_height(
|
||||
group, xslot, yslot, (int)offset.x + (terrainSize - 1) / 2,
|
||||
(int)offset.z + (terrainSize - 1) / 2);
|
||||
group, (long)position.x, (long)position.z);
|
||||
return height;
|
||||
}
|
||||
float TerrainModule::get_world_x(int x)
|
||||
{
|
||||
return HeightData::get_singleton()->get_world_x(x);
|
||||
}
|
||||
float TerrainModule::get_world_y(int y)
|
||||
{
|
||||
return HeightData::get_singleton()->get_world_y(y);
|
||||
}
|
||||
int TerrainModule::get_img_x(float world_x)
|
||||
{
|
||||
return HeightData::get_singleton()->get_img_x(world_x);
|
||||
}
|
||||
int TerrainModule::get_img_y(float world_z)
|
||||
{
|
||||
return HeightData::get_singleton()->get_img_y(world_z);
|
||||
}
|
||||
void TerrainModule::update_heightmap(const Ogre::Image &heightmap)
|
||||
{
|
||||
return HeightData::get_singleton()->update_heightmap(heightmap);
|
||||
}
|
||||
void TerrainModule::save_heightmap()
|
||||
{
|
||||
HeightData::get_singleton()->save_heightmap();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user