void create_textures() { levels = new gcm_level[L]; level_property_block = new MaterialPropertyBlock(); int2 origin = new int2(); origin.x -= M; origin.y -= M; for (int i = 0; i < L; ++i) { origin.x -= W * (1 << i); origin.y -= W * (1 << i); levels[i] = new gcm_level(); levels[i].texture = new RenderTexture(SIZE + 1, SIZE + 1, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default); //levels[i].texture.filterMode = FilterMode.Point; levels[i].scale = 1 << i; levels[i].origin = origin; levels[i].material = new Material(level_shader); levels[i].material.name = "gcm_level_" + i; levels[i].material.SetFloat("_tex_width", SIZE + 1); levels[i].material.SetTexture("_MainTex", levels[i].texture); } }
void update_clip_map(gcm_level lv) { int2 pos = new int2(terrain_offset) + lv.origin; float start_x = (float)pos.x / (float)heightmap.width; float start_y = (float)pos.y / (float)heightmap.width; float texture_width = ((float)SIZE_FPW2 / (float)heightmap.width) * lv.scale; float texel_width = 1f / (float)heightmap.width; level_map_material.SetTexture("_MainTex", heightmap); level_map_material.SetVector("_Input", new Vector4(start_x, start_y, texture_width, texel_width)); Graphics.Blit(heightmap, lv.texture, level_map_material); }
void draw_center(gcm_level lv) { float t = W / SIZE_FPW2; float texel = 1f / SIZE_FPW2; // 2 x trim around center draw_mesh(lv, grid_L[L_XMIN_YMIN], lv.origin.x + W, lv.origin.y + W, t, t); draw_mesh(lv, grid_L[L_XMAX_YMAX], lv.origin.x + W, lv.origin.y + W, t, t); // 4 x MxM blocks in center draw_mesh(lv, grid_MxM, lv.origin.x + M, lv.origin.y + M, t + texel, t + texel); draw_mesh(lv, grid_MxM, lv.origin.x + M + W, lv.origin.y + M, t + texel + t, t + texel); draw_mesh(lv, grid_MxM, lv.origin.x + M, lv.origin.y + M + W, t + texel, t + texel + t); draw_mesh(lv, grid_MxM, lv.origin.x + M + W, lv.origin.y + M + W, t + texel + t, t + texel + t); }
void OnDrawGizmos() { if (levels != null) { for (int i = 0; i < L && i < levels.Length; ++i) { gcm_level lv = levels[i]; //Gizmos.color = Color.white; //Gizmos.DrawWireSphere(lv.origin.v3_xz, 0.25f); //Bounds b = new Bounds(); //b.SetMinMax(lv.min_inner.v3_xz, lv.max_inner.v3_xz); //Gizmos.color = Color.red; //Gizmos.DrawWireCube(b.center, b.size); //Gizmos.DrawLine(b.min - new Vector3(0, 32, 0), b.min + new Vector3(0, 32, 0)); //Gizmos.DrawLine(b.max - new Vector3(0, 32, 0), b.max + new Vector3(0, 32, 0)); //Gizmos.DrawLine(new Vector3(b.min.x, 0, b.max.z) - new Vector3(0, 32, 0), new Vector3(b.min.x, 0, b.max.z) + new Vector3(0, 32, 0)); //Gizmos.DrawLine(new Vector3(b.max.x, 0, b.min.z) - new Vector3(0, 32, 0), new Vector3(b.max.x, 0, b.min.z) + new Vector3(0, 32, 0)); } } }
void update_clip_map (gcm_level lv) { int2 pos = new int2(terrain_offset) + lv.origin; float start_x = (float)pos.x / (float)heightmap.width; float start_y = (float)pos.y / (float)heightmap.width; float texture_width = ((float)SIZE_FPW2 / (float)heightmap.width) * lv.scale; float texel_width = 1f / (float)heightmap.width; level_map_material.SetTexture("_MainTex", heightmap); level_map_material.SetVector("_Input", new Vector4(start_x, start_y, texture_width, texel_width)); Graphics.Blit(heightmap, lv.texture, level_map_material); }
void draw_center (gcm_level lv) { float t = W / SIZE_FPW2; float texel = 1f / SIZE_FPW2; // 2 x trim around center draw_mesh(lv, grid_L[L_XMIN_YMIN], lv.origin.x + W, lv.origin.y + W, t, t); draw_mesh(lv, grid_L[L_XMAX_YMAX], lv.origin.x + W, lv.origin.y + W, t, t); // 4 x MxM blocks in center draw_mesh(lv, grid_MxM, lv.origin.x + M, lv.origin.y + M, t + texel, t + texel); draw_mesh(lv, grid_MxM, lv.origin.x + M + W, lv.origin.y + M, t + texel + t, t + texel); draw_mesh(lv, grid_MxM, lv.origin.x + M, lv.origin.y + M + W, t + texel, t + texel + t); draw_mesh(lv, grid_MxM, lv.origin.x + M + W, lv.origin.y + M + W, t + texel + t, t + texel + t); }
void draw_mesh(gcm_level l, Mesh m, float pos_x, float pos_y, float tex_x, float tex_y) { Graphics.DrawMesh(m, new Vector4(pos_x, 0, pos_y), Quaternion.identity, l.material, 0, null, 0, get_properties(l.scale, pos_x, pos_y, tex_x, tex_y)); }
void create_textures () { levels = new gcm_level[L]; level_property_block = new MaterialPropertyBlock(); int2 origin = new int2(); origin.x -= M; origin.y -= M; for (int i = 0; i < L; ++i) { origin.x -= W * (1 << i); origin.y -= W * (1 << i); levels[i] = new gcm_level(); levels[i].texture = new RenderTexture(SIZE + 1, SIZE + 1, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default); //levels[i].texture.filterMode = FilterMode.Point; levels[i].scale = 1 << i; levels[i].origin = origin; levels[i].material = new Material(level_shader); levels[i].material.name = "gcm_level_" + i; levels[i].material.SetFloat("_tex_width", SIZE + 1); levels[i].material.SetTexture("_MainTex", levels[i].texture); } }
void draw_level(int level) { gcm_level lv = levels[level]; bool update = false; if (level > 0) { var min = levels[level - 1].min; var max = levels[level - 1].max; var min_inner = lv.min_inner; var max_inner = lv.max_inner; while (min_inner.x > min.x) { lv.origin.x -= lv.scale * 2; min = levels[level - 1].min; max = levels[level - 1].max; min_inner = lv.min_inner; max_inner = lv.max_inner; update = true; } while (min_inner.y > min.y) { lv.origin.y -= lv.scale * 2; min = levels[level - 1].min; max = levels[level - 1].max; min_inner = lv.min_inner; max_inner = lv.max_inner; update = true; } while (max_inner.x < max.x) { lv.origin.x += lv.scale * 2; min = levels[level - 1].min; max = levels[level - 1].max; min_inner = lv.min_inner; max_inner = lv.max_inner; update = true; } while (max_inner.y < max.y) { lv.origin.y += lv.scale * 2; min = levels[level - 1].min; max = levels[level - 1].max; min_inner = lv.min_inner; max_inner = lv.max_inner; update = true; } } else { while (movement.x >= 2) { lv.origin.x -= 2; movement.x -= 2; update = true; } while (movement.x <= -2) { lv.origin.x += 2; movement.x += 2; update = true; } while (movement.y >= 2) { lv.origin.y -= 2; movement.y -= 2; update = true; } while (movement.y <= -2) { lv.origin.y += 2; movement.y += 2; update = true; } } int w = W * lv.scale; int small = 2 * lv.scale; float t = W / SIZE_FPW2; float small_t = 2f / SIZE_FPW2; float right = (SIZE - 1) * lv.scale; float top = (SIZE - 1) * lv.scale; float tex_edge = t + t + t + small_t; if (update) { update_clip_map(lv); } if (level == 0) { draw_center(lv); } else { var min = levels[level - 1].min; var max = levels[level - 1].max; var min_inner = lv.min_inner; var max_inner = lv.max_inner; if (min.x == min_inner.x) { if (min.y == min_inner.y) { draw_mesh(lv, grid_L[L_XMAX_YMAX], lv.origin.x + w, lv.origin.y + w, t, t); } else { draw_mesh(lv, grid_L[L_XMAX_YMIN], lv.origin.x + w, lv.origin.y + w, t, t); } } else { if (min.y == min_inner.y) { draw_mesh(lv, grid_L[L_XMIN_YMAX], lv.origin.x + w, lv.origin.y + w, t, t); } else { draw_mesh(lv, grid_L[L_XMIN_YMIN], lv.origin.x + w, lv.origin.y + w, t, t); } } } // Bottom draw_mesh(lv, grid_MxM, lv.origin.x, lv.origin.y, 0, 0); draw_mesh(lv, grid_MxM, lv.origin.x + w, lv.origin.y, t, 0); draw_mesh(lv, grid_Mx3, lv.origin.x + w + w, lv.origin.y, t + t, 0); draw_mesh(lv, grid_MxM, lv.origin.x + w + w + small, lv.origin.y, t + t + small_t, 0); draw_mesh(lv, grid_MxM, lv.origin.x + w + w + small + w, lv.origin.y, t + t + small_t + t, 0); // Left draw_mesh(lv, grid_MxM, lv.origin.x, lv.origin.y + w, 0, t); draw_mesh(lv, grid_3xM, lv.origin.x, lv.origin.y + w + w, 0, t + t); draw_mesh(lv, grid_MxM, lv.origin.x, lv.origin.y + w + w + small, 0, t + t + small_t); // Right draw_mesh(lv, grid_MxM, lv.origin.x + right - w, lv.origin.y + w, tex_edge, t); draw_mesh(lv, grid_3xM, lv.origin.x + right - w, lv.origin.y + w + w, tex_edge, t + t); draw_mesh(lv, grid_MxM, lv.origin.x + right - w, lv.origin.y + w + w + small, tex_edge, t + t + small_t); // Top draw_mesh(lv, grid_MxM, lv.origin.x, lv.origin.y + top - w, 0, tex_edge); draw_mesh(lv, grid_MxM, lv.origin.x + w, lv.origin.y + top - w, t, tex_edge); draw_mesh(lv, grid_Mx3, lv.origin.x + w + w, lv.origin.y + top - w, t + t, tex_edge); draw_mesh(lv, grid_MxM, lv.origin.x + w + w + small, lv.origin.y + top - w, t + t + small_t, tex_edge); draw_mesh(lv, grid_MxM, lv.origin.x + w + w + small + w, lv.origin.y + top - w, t + t + small_t + t, tex_edge); }