nuclear@1: #include "level.h" nuclear@1: nuclear@1: #include "opt.h" nuclear@1: nuclear@1: Level::Level() nuclear@1: { nuclear@1: terrain = 0; nuclear@4: world_size = Vector3(1, 1, 1); nuclear@1: } nuclear@1: nuclear@1: Level::~Level() nuclear@1: { nuclear@1: delete terrain; nuclear@1: } nuclear@1: nuclear@3: static float terrain_func(float x, float y, float z) nuclear@3: { nuclear@3: float nx = (x * 2.0 - 1.0) * 0.9; nuclear@3: float ny = (y * 2.0 - 1.0) * 0.9; nuclear@3: float valley = nx * nx + ny * ny; nuclear@3: nuclear@3: float s = opt.gen_noise_scale; nuclear@4: float noise = 0.2 * fbm2(x * s, y * s, 4) * (valley + 0.25); nuclear@3: float grad = 0.75 - z + noise + valley * 0.4; nuclear@3: nuclear@3: return grad; nuclear@3: } nuclear@3: nuclear@1: void Level::generate() nuclear@1: { nuclear@1: delete terrain; nuclear@1: nuclear@1: int xsz = opt.world_size[0]; nuclear@1: int ysz = opt.world_size[1]; nuclear@1: int zsz = opt.world_size[2]; nuclear@1: nuclear@1: terrain = new Volume(xsz, ysz, zsz); nuclear@1: nuclear@1: for(int i=0; iset_voxel(i, j, k, voxel); nuclear@1: } nuclear@1: } nuclear@1: } nuclear@4: nuclear@4: // generate some blobs nuclear@4: for(int i=0; i (b) ? (b) : (x))) nuclear@4: nuclear@4: const Vector4 &Level::get_voxel(const Vector3 &pos) const nuclear@4: { nuclear@4: Vector3 p = pos / world_size + Vector3(0.5, 0.5, 0.5); nuclear@4: nuclear@4: int xsz = terrain->get_size(0); nuclear@4: int ysz = terrain->get_size(1); nuclear@4: int zsz = terrain->get_size(2); nuclear@4: nuclear@4: int i = (int)(p.x * xsz); nuclear@4: int j = (int)(p.y * ysz); nuclear@4: int k = (int)(p.z * zsz); nuclear@4: nuclear@4: return terrain->get_voxel(CLAMP(i, 0, xsz - 1), CLAMP(j, 0, ysz - 1), CLAMP(k, 0, zsz - 1)); nuclear@4: } nuclear@4: nuclear@4: Vector3 Level::calc_normal(const Vector3 &pos) const nuclear@4: { nuclear@4: int xsz = terrain->get_size(0); nuclear@4: int ysz = terrain->get_size(1); nuclear@4: int zsz = terrain->get_size(2); nuclear@4: nuclear@4: float dx = world_size.x / (float)xsz; nuclear@4: float dy = world_size.y / (float)ysz; nuclear@4: float dz = world_size.z / (float)zsz; nuclear@4: nuclear@4: float dfdx = get_voxel(pos + Vector3(dx, 0, 0)).w - get_voxel(pos - Vector3(dx, 0, 0)).w; nuclear@4: float dfdy = get_voxel(pos + Vector3(0, dy, 0)).w - get_voxel(pos - Vector3(0, dy, 0)).w; nuclear@4: float dfdz = get_voxel(pos + Vector3(0, 0, dz)).w - get_voxel(pos - Vector3(0, 0, dz)).w; nuclear@4: nuclear@4: return Vector3(dfdx, dfdy, dfdz); nuclear@4: } nuclear@4: nuclear@4: bool Level::collision(const Vector3 &pos0, const Vector3 &pos1, Vector3 *outpos, Vector3 *outnorm) const nuclear@4: { nuclear@4: Vector4 vox0 = get_voxel(pos0); nuclear@4: Vector4 vox1 = get_voxel(pos1); nuclear@4: nuclear@4: if(vox0.w < 0.5 && vox1.w >= 0.5) { nuclear@4: *outpos = lerp(pos0, pos1, 0.5); // TODO nuclear@4: *outnorm = calc_normal(*outpos); nuclear@4: return true; nuclear@4: } nuclear@4: return false; nuclear@4: }