Updates
This commit is contained in:
@@ -31,77 +31,30 @@
|
||||
namespace ECS
|
||||
{
|
||||
|
||||
class FlatTerrainDefiner
|
||||
: public Ogre::TerrainPagedWorldSection::TerrainDefiner,
|
||||
public Ogre::FrameListener {
|
||||
Ogre::SceneManager *mScnMgr;
|
||||
Ogre::Bullet::DynamicsWorld *mWorld;
|
||||
struct gen_collider {
|
||||
Ogre::TerrainGroup *group;
|
||||
long x;
|
||||
long y;
|
||||
};
|
||||
std::deque<struct gen_collider> collider_queue;
|
||||
Ogre::Image img, img_noise, img_brushes;
|
||||
|
||||
public:
|
||||
FlatTerrainDefiner(Ogre::SceneManager *scm,
|
||||
Ogre::Bullet::DynamicsWorld *world)
|
||||
: Ogre::TerrainPagedWorldSection::TerrainDefiner()
|
||||
, Ogre::FrameListener()
|
||||
, mScnMgr(scm)
|
||||
, mWorld(world)
|
||||
#define BRUSH_SIZE 64
|
||||
struct HeightData {
|
||||
Ogre::Image img;
|
||||
Ogre::Image img_brushes;
|
||||
Ogre::Image img_noise;
|
||||
static HeightData *singleton;
|
||||
HeightData()
|
||||
{
|
||||
Ogre::Root::getSingleton().addFrameListener(this);
|
||||
img.load(
|
||||
"world_map.png",
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||
img_noise.load(
|
||||
"terrain.png",
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||
img_brushes.load(
|
||||
"brushes.png",
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||
img_noise.load(
|
||||
"terrain.png",
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||
}
|
||||
|
||||
private:
|
||||
float get_noise_height(const Ogre::Vector2 &worldOffset, int x, int y)
|
||||
static HeightData *get_singleton()
|
||||
{
|
||||
int h;
|
||||
Ogre::Vector2 noisePoint;
|
||||
|
||||
struct noise_types {
|
||||
Ogre::Vector2 noiseOfft;
|
||||
float noiseMul;
|
||||
float noiseBias;
|
||||
float noiseAmp;
|
||||
};
|
||||
static struct noise_types noise_pass[] = {
|
||||
{ { -100.0f, 70.0f }, 10.2f, -0.55f, 5.0f },
|
||||
{ { -130.0f, 55.0f }, 5.35f, -0.55f, 1.0f }
|
||||
};
|
||||
static float noise_values[] = { 0.0f, 0.0f };
|
||||
for (h = 0; h < (int)sizeof(noise_values) /
|
||||
(int)sizeof(noise_values[0]);
|
||||
h++) {
|
||||
noisePoint = (worldOffset + Ogre::Vector2(x, y) +
|
||||
noise_pass[h].noiseOfft) *
|
||||
noise_pass[h].noiseMul;
|
||||
int noise_x =
|
||||
(int)(noisePoint.x + img_noise.getWidth() / 2) %
|
||||
img_noise.getWidth();
|
||||
int noise_y = (int)(noisePoint.y +
|
||||
img_noise.getHeight() / 2) %
|
||||
img_noise.getHeight();
|
||||
Ogre::ColourValue noise_color =
|
||||
img_noise.getColourAt(noise_x, noise_y, 0);
|
||||
noise_values[h] =
|
||||
(noise_color.r + noise_pass[h].noiseBias) *
|
||||
noise_pass[h].noiseAmp;
|
||||
}
|
||||
return noise_values[0] + noise_values[1];
|
||||
if (!singleton)
|
||||
singleton = new HeightData();
|
||||
return singleton;
|
||||
}
|
||||
#define BRUSH_SIZE 64
|
||||
float get_brush_height(int id, int x, int y)
|
||||
{
|
||||
int m = 0;
|
||||
@@ -149,7 +102,96 @@ private:
|
||||
out:
|
||||
return height;
|
||||
}
|
||||
float get_noise_height(const Ogre::Vector2 &worldOffset, int x, int y)
|
||||
{
|
||||
int h;
|
||||
Ogre::Vector2 noisePoint;
|
||||
|
||||
struct noise_types {
|
||||
Ogre::Vector2 noiseOfft;
|
||||
float noiseMul;
|
||||
float noiseBias;
|
||||
float noiseAmp;
|
||||
};
|
||||
static struct noise_types noise_pass[] = {
|
||||
{ { -100.0f, 70.0f }, 10.2f, -0.55f, 5.0f },
|
||||
{ { -130.0f, 55.0f }, 5.35f, -0.55f, 1.0f }
|
||||
};
|
||||
static float noise_values[] = { 0.0f, 0.0f };
|
||||
for (h = 0; h < (int)sizeof(noise_values) /
|
||||
(int)sizeof(noise_values[0]);
|
||||
h++) {
|
||||
noisePoint = (worldOffset + Ogre::Vector2(x, y) +
|
||||
noise_pass[h].noiseOfft) *
|
||||
noise_pass[h].noiseMul;
|
||||
int noise_x =
|
||||
(int)(noisePoint.x + img_noise.getWidth() / 2) %
|
||||
img_noise.getWidth();
|
||||
int noise_y = (int)(noisePoint.y +
|
||||
img_noise.getHeight() / 2) %
|
||||
img_noise.getHeight();
|
||||
Ogre::ColourValue noise_color =
|
||||
img_noise.getColourAt(noise_x, noise_y, 0);
|
||||
noise_values[h] =
|
||||
(noise_color.r + noise_pass[h].noiseBias) *
|
||||
noise_pass[h].noiseAmp;
|
||||
}
|
||||
return noise_values[0] + noise_values[1];
|
||||
}
|
||||
float get_height(Ogre::TerrainGroup *terrainGroup, long x, long y,
|
||||
int j, int i)
|
||||
{
|
||||
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;
|
||||
float mheight =
|
||||
Ogre::Math::lerp(
|
||||
brush_height1, brush_height0,
|
||||
HeightData::get_singleton()->get_base_height(
|
||||
worldOffset, j, i)) *
|
||||
120.0f;
|
||||
float height = mheight;
|
||||
if (mheight > 0.5f)
|
||||
height += 2.0f + get_noise_height(worldOffset, j, i);
|
||||
else if (mheight < -0.5f)
|
||||
height -= 2.0f + get_noise_height(worldOffset, j, i);
|
||||
return height;
|
||||
}
|
||||
};
|
||||
HeightData *HeightData::singleton = nullptr;
|
||||
|
||||
class FlatTerrainDefiner
|
||||
: public Ogre::TerrainPagedWorldSection::TerrainDefiner,
|
||||
public Ogre::FrameListener {
|
||||
Ogre::SceneManager *mScnMgr;
|
||||
Ogre::Bullet::DynamicsWorld *mWorld;
|
||||
struct gen_collider {
|
||||
Ogre::TerrainGroup *group;
|
||||
long x;
|
||||
long y;
|
||||
};
|
||||
std::deque<struct gen_collider> collider_queue;
|
||||
|
||||
public:
|
||||
FlatTerrainDefiner(Ogre::SceneManager *scm,
|
||||
Ogre::Bullet::DynamicsWorld *world)
|
||||
: Ogre::TerrainPagedWorldSection::TerrainDefiner()
|
||||
, Ogre::FrameListener()
|
||||
, mScnMgr(scm)
|
||||
, mWorld(world)
|
||||
{
|
||||
Ogre::Root::getSingleton().addFrameListener(this);
|
||||
}
|
||||
|
||||
private:
|
||||
public:
|
||||
void define(Ogre::TerrainGroup *terrainGroup, long x, long y) override
|
||||
{
|
||||
@@ -158,37 +200,15 @@ public:
|
||||
MEMCATEGORY_GEOMETRY);
|
||||
// float *heightMapCollider = OGRE_ALLOC_T(
|
||||
// float, terrainSize *terrainSize, MEMCATEGORY_GEOMETRY);
|
||||
Ogre::Vector2 worldOffset(Ogre::Real(x * (terrainSize - 1)),
|
||||
Ogre::Real(y * (terrainSize - 1)));
|
||||
Ogre::Vector2 worldOrigin =
|
||||
Ogre::Vector2(img.getWidth(), img.getHeight()) * 0.5f;
|
||||
// Ogre::Vector2 worldOrigin =
|
||||
// Ogre::Vector2(img.getWidth(), img.getHeight()) * 0.5f;
|
||||
float chunk = 128.0f;
|
||||
Ogre::Vector2 revisedValuePoint;
|
||||
for (int i = 0; i < terrainSize; i++)
|
||||
for (int j = 0; j < terrainSize; j++) {
|
||||
float brush_height0 =
|
||||
get_brush_height(0, j % BRUSH_SIZE,
|
||||
i % BRUSH_SIZE) -
|
||||
0.55f;
|
||||
float brush_height1 =
|
||||
get_brush_height(1, j % BRUSH_SIZE,
|
||||
i % BRUSH_SIZE) -
|
||||
0.55f;
|
||||
float mheight =
|
||||
Ogre::Math::lerp(
|
||||
brush_height1, brush_height0,
|
||||
get_base_height(worldOffset, j,
|
||||
i)) *
|
||||
120.0f;
|
||||
float height = mheight;
|
||||
if (mheight > 0.5f)
|
||||
height += 2.0f +
|
||||
get_noise_height(worldOffset,
|
||||
j, i);
|
||||
else if (mheight < -0.5f)
|
||||
height -= 2.0f +
|
||||
get_noise_height(worldOffset,
|
||||
j, i);
|
||||
float height =
|
||||
HeightData::get_singleton()->get_height(
|
||||
terrainGroup, x, y, j, i);
|
||||
|
||||
// height = -2.0f;
|
||||
heightMap[i * terrainSize + j] = height;
|
||||
@@ -277,6 +297,26 @@ public:
|
||||
created = true;
|
||||
}
|
||||
collider_queue.pop_front();
|
||||
// FIXME: create entities and components instead
|
||||
Ogre::SceneNode *items =
|
||||
terrain->_getRootSceneNode()
|
||||
->createChildSceneNode();
|
||||
for (int i = 0; i < ECS::get<PlacementObjects>()
|
||||
.altar_items.size();
|
||||
i++) {
|
||||
const struct PlacementObjects::item &item =
|
||||
ECS::get<PlacementObjects>()
|
||||
.altar_items[i];
|
||||
Ogre::Entity *ent =
|
||||
group->getSceneManager()
|
||||
->createEntity(
|
||||
item.entity);
|
||||
Ogre::SceneNode *what =
|
||||
items->createChildSceneNode();
|
||||
what->attachObject(ent);
|
||||
what->setOrientation(item.rotation);
|
||||
what->setPosition(item.position);
|
||||
}
|
||||
} else {
|
||||
output.push_back(collider_queue.front());
|
||||
collider_queue.pop_front();
|
||||
@@ -433,6 +473,7 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
|
||||
terrain.mTerrainGroup->freeTemporaryResources();
|
||||
std::cout << "Terrain setup done\n";
|
||||
ECS::get().set<PlacementObjects>({});
|
||||
}
|
||||
if (sun.mSun &&
|
||||
priv.mSunUpdate.getMilliseconds() > 1000) {
|
||||
@@ -468,5 +509,113 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
ECS::get().add<TerrainReady>();
|
||||
}
|
||||
});
|
||||
ecs.system<const Terrain, PlacementObjects>("UpdatePlacementObjects")
|
||||
.kind(flecs::OnUpdate)
|
||||
.each([](const Terrain &terrain, PlacementObjects &placement) {
|
||||
if (placement.altar_items.size() == 0) {
|
||||
struct PlacementObjects::item item;
|
||||
int i, j;
|
||||
int worldSize = terrain.mTerrainGroup
|
||||
->getTerrainWorldSize();
|
||||
uint16_t terrainSize =
|
||||
terrain.mTerrainGroup->getTerrainSize();
|
||||
item.entity = "altar.glb";
|
||||
item.rotation = Ogre::Quaternion(0, 0, 0, 1);
|
||||
item.position = Ogre::Vector3(0, 0, 0);
|
||||
float height =
|
||||
HeightData::get_singleton()->get_height(
|
||||
terrain.mTerrainGroup, 0, 0, 0,
|
||||
0);
|
||||
item.position.y = height;
|
||||
placement.altar_items.push_back(item);
|
||||
for (i = -64000; i < 64000; i += 1000)
|
||||
for (j = -64000; j < 64000; j += 1000) {
|
||||
if (i == 0 && j == 0)
|
||||
continue;
|
||||
Ogre::Vector3 position(i, 0, j);
|
||||
long xslot, yslot;
|
||||
terrain.mTerrainGroup
|
||||
->convertWorldPositionToTerrainSlot(
|
||||
position,
|
||||
&xslot, &yslot);
|
||||
Ogre::Vector3 slotpos;
|
||||
terrain.mTerrainGroup
|
||||
->convertTerrainSlotToWorldPosition(
|
||||
xslot, yslot,
|
||||
&slotpos);
|
||||
Ogre::Vector3 offset =
|
||||
(position - slotpos) *
|
||||
terrainSize / worldSize;
|
||||
height =
|
||||
HeightData::get_singleton()
|
||||
->get_height(
|
||||
terrain.mTerrainGroup,
|
||||
xslot,
|
||||
yslot,
|
||||
(int)offset.x +
|
||||
(terrainSize -
|
||||
1) / 2,
|
||||
(int)offset.z +
|
||||
(terrainSize -
|
||||
1) / 2);
|
||||
#if 0
|
||||
height =
|
||||
terrain.mTerrainGroup
|
||||
->getHeightAtWorldPosition(
|
||||
position);
|
||||
#endif
|
||||
if (height > -9.0f)
|
||||
continue;
|
||||
std::cout << "worldSize: "
|
||||
<< worldSize - 1
|
||||
<< std::endl;
|
||||
std::cout << "height: " << i
|
||||
<< " " << j << " "
|
||||
<< height
|
||||
<< std::endl;
|
||||
item.entity = "altar.glb";
|
||||
item.rotation =
|
||||
Ogre::Quaternion(0, 0,
|
||||
0, 1);
|
||||
position.y = height;
|
||||
item.position = position;
|
||||
placement.altar_items.push_back(
|
||||
item);
|
||||
}
|
||||
for (i = 0; i < placement.altar_items.size();
|
||||
i++) {
|
||||
std::cout << "placement: " << i << " "
|
||||
<< placement.altar_items[i]
|
||||
.position
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
flecs::entity player = ECS::player;
|
||||
CharacterLocation &loc =
|
||||
player.get_mut<CharacterLocation>();
|
||||
float height =
|
||||
get_height(terrain.mTerrainGroup, loc.position);
|
||||
loc.position.y = height + 0.0f;
|
||||
player.get<CharacterBase>().mBodyNode->setPosition(
|
||||
loc.position);
|
||||
player.get<CharacterBase>().mBodyNode->setOrientation(
|
||||
Ogre::Quaternion());
|
||||
player.modified<CharacterLocation>();
|
||||
});
|
||||
}
|
||||
float TerrainModule::get_height(Ogre::TerrainGroup *group,
|
||||
const Ogre::Vector3 &position)
|
||||
{
|
||||
int worldSize = group->getTerrainWorldSize();
|
||||
uint16_t terrainSize = group->getTerrainSize();
|
||||
long xslot, yslot;
|
||||
group->convertWorldPositionToTerrainSlot(position, &xslot, &yslot);
|
||||
Ogre::Vector3 slotpos;
|
||||
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);
|
||||
return height;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user