rng = require("rng") shim = require("shader_shim") world = require("world") color = require("color") win = require("window") settings = require("settings") sprites = require("world.sprites") ecs = require("ecs") fish = require("spawn_fish") gen = {} -- Generate roughly rectangular islands -- Stategy: generate a series of points, if we're in the first 1/4, go roughly right, -- in the second 1/4, roughtly up, in the 3rd 1/4 roughly left, and in the 4th quarter roughtly down, finally joining up at the end -- We find the smallest aabb box in this line, and use points on this box as the other side for triangles. n_points = 100 point_distance = 1 sides = 4 gen.generate = (seed) -> rg = rng.generator(seed) normal = (avg, std) -> --print("normal with", avg, std) rg1, rg2 = rg(),rg() --print("rgs:",rg1, rg2) -- Box-Muller transform bm = math.sqrt(-2 * math.log(rg1)) * math.cos(2 * math.pi * rg2) --print("bm was:",bm) -- Box-Muller gives us std = e^-0.5 , avg = 0 ((bm / math.exp(-1/2)) * std) + avg shoreline = {} shoreline[1] = vec2(0,0) aabb_sides = { {"y",math.max,"b"}, {"x",math.min,"r"}, {"y",math.min,"t",}, {"x",math.max,"l"} } aabb = { b: n_points * point_distance r: n_points * point_distance t: -n_points * point_distance l: -n_points * point_distance } z = 0 for i = 1, sides for j = 1, n_points / sides -- remap i (1->4) to (0 -> 2pi) avg_direction = ((i-1)/sides) * (2 * math.pi) std_direction = math.pi / 6 rng_direction = normal(avg_direction, std_direction) --print("rng_direction ended up being:", rng_direction) point = shoreline[#shoreline] + vec2(math.cos(rng_direction) * point_distance, math.sin(rng_direction) * point_distance) shoreline[#shoreline + 1] = point --print("point:", point) --print("prev:",aabb[aabb_sides[i][3]]) aabb[aabb_sides[i][3]] = aabb_sides[i][2](aabb[aabb_sides[i][3]],point[aabb_sides[i][1]]) --print("Generated shoreline:",shoreline) --print("And aabb box:" ,aabb) -- Now that we have the shorline, generate the geometry -- every point after the first needs to generate 2 triangles, 6 vertexes, each vertex is a vec3, 3 floats, 4 bytes per float geom = am.buffer(((n_points * 2) - 4) * 6 * 3 * 4) -- 4 corners only get 1 triangle gview = geom\view("vec3") gview[1] = vec3(shoreline[1].x, shoreline[1].y,z) gview[2] = vec3(aabb.l, aabb.b,z) gview[3] = vec3(shoreline[npoints - 1].x, shoreline[npoints - 1].y, z) gi = 4 only1 = {[25]: true, [50]: true, [75]: true} for i = 2, npoints gview[gi] = vec3(shoreline[i].x, shoreline[i].y, z) if i < 25 gview[gi+1] = 1 aspect = win.width / win.height aspect_inv = win.height / win.width class IslandGraphicsComponent extends world.GraphicsComponent action: (bind) => bind.time = am.current_time! % 1000 -- loop back around so noise doesn't look wonky after a while --bind.lamp1 = vec4(world.world_x + 3.35, world.world_y + 1.9, 0, 2.2) --no idea why these magic numbers --bind.lamp1 = vec4(world.world_x + (0.5 * 4 * aspect) - 0.3, world.world_y + (0.5 * 4 * (aspect_inv)) + 0.7, 0, 2.2) --no idea why these magic numbers --bind.lamp2 = vec4(0,0,0,3) buf_size: () => squares = 16 triangles_per_square = 2 vertexes_per_triangle = 3 floats_per_vertex = 3 squares * triangles_per_square * vertexes_per_triangle --6 populate_buf: (geom_view, normal_view, offset) => z = 0 size = 10 --@lamp = world.level.add_lamp(vec4(0,0,10,2)) fuv = sprites.rocks_normal floor = (geom, uv, offset, start, finish) -> geom[offset + 0] = vec3(start.x,start.y,z) geom[offset + 1] = vec3(start.x,finish.y,z) geom[offset + 2] = vec3(finish.x,finish.y,z) geom[offset + 3] = vec3(finish.x,finish.y,z) geom[offset + 4] = vec3(finish.x,start.y,z) geom[offset + 5] = vec3(start.x,start.y,z) normal_view[offset + 0] = vec2(fuv.s1, fuv.t1) normal_view[offset + 1] = vec2(fuv.s1, fuv.t2) normal_view[offset + 2] = vec2(fuv.s2, fuv.t2) normal_view[offset + 3] = vec2(fuv.s2, fuv.t2) normal_view[offset + 4] = vec2(fuv.s2, fuv.t1) normal_view[offset + 5] = vec2(fuv.s1, fuv.t1) x_panels = 4 y_panels = 4 x_stride = (size * 2) / x_panels y_stride = (size * 2) / y_panels j = 1 for floorx = 1,x_panels for floory = 1,y_panels floor( geom_view, normal_view, j, vec2(-size + (x_stride*(floorx-1)), -size + (y_stride*(floory-1))), vec2(-size + (x_stride*floorx), -size + (y_stride*floory)) ) j += 6 class WaterGraphicsComponent extends world.GraphicsComponent action: (bind) => bind.time = am.current_time! % 1000 buf_size: () => 24 populate_buf: (geom_view, normal_view, offset) => z = 1 island_size = 10 - 1 water_size = 20 uv = sprites.sea_normal --down geom_view[1] = vec3(-water_size,-water_size,z) geom_view[2] = vec3(-island_size,-island_size,z) geom_view[3] = vec3(island_size,-island_size,z) geom_view[4] = vec3(island_size,-island_size,z) geom_view[5] = vec3(water_size,-water_size,z) geom_view[6] = vec3(-water_size,-water_size,z) --left geom_view[7] = vec3(-water_size,-water_size,z) geom_view[8] = vec3(-island_size,island_size,z) geom_view[9] = vec3(-island_size,-island_size,z) geom_view[10] = vec3(-water_size,-water_size,z) geom_view[11] = vec3(-water_size,water_size,z) geom_view[12] = vec3(-island_size,island_size,z) --top geom_view[13] = vec3(-water_size,water_size,z) geom_view[14] = vec3(water_size,water_size,z) geom_view[15] = vec3(-island_size,island_size,z) geom_view[16] = vec3(-island_size,island_size,z) geom_view[17] = vec3(water_size,water_size,z) geom_view[18] = vec3(island_size,island_size,z) --right geom_view[19] = vec3(island_size,island_size,z) geom_view[20] = vec3(water_size,water_size,z) geom_view[21] = vec3(island_size,-island_size,z) geom_view[22] = vec3(water_size,water_size,z) geom_view[23] = vec3(water_size,-water_size,z) geom_view[24] = vec3(island_size,-island_size,z) normal_view[1] = vec2(uv.s1,uv.t1) normal_view[2] = vec2(uv.s1,uv.t1) normal_view[3] = vec2(uv.s2,uv.t1) normal_view[4] = vec2(uv.s2,uv.t1) normal_view[5] = vec2(uv.s2,uv.t1) normal_view[6] = vec2(uv.s1,uv.t1) normal_view[7] = vec2(uv.s1,uv.t1) normal_view[8] = vec2(uv.s1,uv.t2) normal_view[9] = vec2(uv.s1,uv.t1) normal_view[10] = vec2(uv.s1,uv.t1) normal_view[11] = vec2(uv.s1,uv.t2) normal_view[12] = vec2(uv.s1,uv.t2) normal_view[13] = vec2(uv.s1,uv.t2) normal_view[14] = vec2(uv.s2,uv.t2) normal_view[15] = vec2(uv.s1,uv.t2) normal_view[16] = vec2(uv.s1,uv.t2) normal_view[17] = vec2(uv.s2,uv.t2) normal_view[18] = vec2(uv.s2,uv.t2) normal_view[19] = vec2(uv.s2,uv.t2) normal_view[20] = vec2(uv.s2,uv.t2) normal_view[21] = vec2(uv.s2,uv.t1) normal_view[22] = vec2(uv.s2,uv.t2) normal_view[23] = vec2(uv.s2,uv.t1) normal_view[24] = vec2(uv.s2,uv.t1) setup: (node) => bind = node("bind") for k,v in pairs(color.am_lake_color) bind[k] = v bind.water = 2 gen.protogen = (seed) -> ecs.Entity(nil, { IslandGraphicsComponent("island") }) ecs.Entity(nil, { water: WaterGraphicsComponent("water") spawner1: fish.SpawnFishComponent("spawner",{},vec4(10.3,-10,15,15)) spawner2: fish.SpawnFishComponent("spawner",{},vec4(-10,10.3,15,15)) spawner3: fish.SpawnFishComponent("spawner",{},vec4(-15,-15,9.7,10)) spawner4: fish.SpawnFishComponent("spawner",{},vec4(-15,-15,10,9.7)) }) --ecs.Entity(nil, { gen