#include "world_terrain_lod.h" #include "world_chunk.h" WorldChunk WorldChunk::create(const Vector3i &loc, const Vector &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 &lod_list) { float d = loc.to_vec3().distance_to(vxform.origin); const List::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 dnoise, Ref vnoise, Ref 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); }