84 lines
2.2 KiB
C++
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);
|
|
}
|
|
|