Files
academy2/modules/world/world_chunk.cpp
2021-07-31 03:37:28 +03:00

84 lines
2.2 KiB
C++

#include "world_terrain_lod.h"
#include "world_chunk.h"
WorldChunk WorldChunk::create(const Vector3i &loc, const Vector<Vector3> &points)
{
int i;
WorldChunk ret;
ret.loc = loc;
ret.aabb.position = loc.to_vec3();
ret.aabb.size = Vector3();
ret.points.append_array(points);
for (i = 0; i < ret.points.size(); i++) {
ret.aabb.expand_to(ret.points[i]);
}
ret.lod = 0;
ret.dirty = true;
return ret;
}
AABB WorldChunk::get_aabb() const
{
return aabb;
}
void WorldChunk::update_lod(const Transform &vxform, const List<WorldTerrainLod> &lod_list)
{
float d = loc.to_vec3().distance_to(vxform.origin);
const List<WorldTerrainLod>::Element *e = lod_list.front();
int i = 0;
int prev_lod = lod;
bool ok = false;
while(e) {
const WorldTerrainLod *l = &e->get();
if (l->in_range(d)) {
lod = i;
ok = true;
break;
}
i++;
e = e->next();
}
if (!ok)
lod = lod_list.size() - 1;
if (prev_lod != lod) {
dirty = true;
printf("lod changed %d -> %d\n", prev_lod, lod);
}
}
void WorldChunk::randomize_transforms(Ref<OpenSimplexNoise> dnoise,
Ref<OpenSimplexNoise> vnoise,
Ref<RandomNumberGenerator> rnd_offset,
float density_scaler)
{
int i, j;
int max_transforms = (int)(points.size() * density_scaler / 4);
transforms.resize(max_transforms);
variance.resize(max_transforms);
int count = 0;
float tpx = vnoise->get_period() * 0.1f;
float dtpx = dnoise->get_period() * 0.15f;
for (i = 0; i < points.size(); i += 4) {
Vector3 u = points[i + 1];
Vector3 v = points[i + 2];
Vector3 w = points[i + 3];
Vector3 pt = points[i];
float density = dnoise->get_noise_3d(pt.x * dtpx, pt.y * dtpx, pt.z * dtpx) * 0.5 + 0.5f;
int mul = (int)(density * density_scaler);
mul += (mul == 0);
for (j = 0; j < mul; j++) {
float r1 = rnd_offset->randf() * 0.5f;
float r2 = rnd_offset->randf() * 0.5f;
float r3 = rnd_offset->randf() * 0.5f;
Vector3 tops = points[i] + r1 * u + r2 * v + r3 * w;
float rot = rnd_offset->randf() * 2.0 * M_PI;
Transform xform = Transform().rotated(Vector3(0, 1, 0), rot);
xform.origin = tops;
transforms.write[count] = xform;
variance.write[count] = vnoise->get_noise_3d(tops.x * tpx, tops.y * tpx, tops.z * tpx) * 0.5 + 0.5f;
count++;
}
}
transforms.resize(count);
variance.resize(count);
}