void generate_sphere_mesh(Mesh *mesh, float *radius_out, int bands) { float latitude_bands = bands; float longitude_bands = bands; float radius = 1.0; u32 vertices_count = (latitude_bands + 1) * (longitude_bands + 1) * 3; u32 normals_count = vertices_count; u32 uv_count = vertices_count; u32 indices_count = latitude_bands * longitude_bands * 6; allocate_mesh(mesh, vertices_count, normals_count, indices_count, uv_count, 0); u32 vertices_index = 0; u32 normals_index = 0; u32 uv_index = 0; u32 indices_index = 0; for (float lat_number = 0; lat_number <= latitude_bands; lat_number++) { float theta = lat_number * pi / latitude_bands; float sinTheta = sin(theta); float cos_theta = cos(theta); for (float long_number = 0; long_number <= longitude_bands; long_number++) { float phi = long_number * 2 * pi / longitude_bands; float sin_phi = sin(phi); float cos_phi = cos(phi); float x = cos_phi * sinTheta; float y = cos_theta; float z = sin_phi * sinTheta; mesh->data.uv[uv_index++] = 1 - (long_number / longitude_bands); mesh->data.uv[uv_index++] = 1 - (lat_number / latitude_bands); mesh->data.vertices[vertices_index++] = radius * x; mesh->data.vertices[vertices_index++] = radius * y; mesh->data.vertices[vertices_index++] = radius * z; mesh->data.normals[normals_index++] = x; mesh->data.normals[normals_index++] = y; mesh->data.normals[normals_index++] = z; } } for (int lat_number = 0; lat_number < latitude_bands; lat_number++) { for (int long_number = 0; long_number < longitude_bands; long_number++) { int first = (lat_number * (longitude_bands + 1)) + long_number; int second = first + longitude_bands + 1; mesh->data.indices[indices_index++] = first + 1; mesh->data.indices[indices_index++] = second; mesh->data.indices[indices_index++] = first; mesh->data.indices[indices_index++] = first + 1; mesh->data.indices[indices_index++] = second + 1; mesh->data.indices[indices_index++] = second; } } *radius_out = radius; }
static int leval_aac_cb(void *data) { int i, nscols, type; double start, stop; int npts; char *formula[MAX_SET_COLS]; Quark *pset, *gr; GVar *t; Leval_ui *ui = (Leval_ui *) data; Grace *grace; gr = ui->gr; type = GetOptionChoice(ui->set_type); nscols = settype_cols(type); if (xv_evalexpr(ui->start, &start) != RETURN_SUCCESS) { errmsg("Start item undefined"); return RETURN_FAILURE; } if (xv_evalexpr(ui->stop, &stop) != RETURN_SUCCESS) { errmsg("Stop item undefined"); return RETURN_FAILURE; } if (xv_evalexpri(ui->npts, &npts) != RETURN_SUCCESS) { errmsg("Number of points undefined"); return RETURN_FAILURE; } TableCommitEdit(ui->mw, FALSE); for (i = 0; i < nscols; i++) { formula[i] = TableGetCell(ui->mw, i, 0); } pset = gapp_set_new(gr); set_set_type(pset, type); grace = grace_from_quark(pset); t = graal_get_var(grace_get_graal(grace), "$t", TRUE); if (t == NULL) { errmsg("Internal error"); return RETURN_FAILURE; } #if 0 if (t->length != 0) { xfree(t->data); t->length = 0; } t->data = allocate_mesh(start, stop, npts); if (t->data == NULL) { return RETURN_FAILURE; } t->length = npts; if (set_set_length(pset, npts) != RETURN_SUCCESS) { quark_free(pset); XCFREE(t->data); t->length = 0; return RETURN_FAILURE; } #endif for (i = 0; i < nscols; i++) { char buf[32], *expr; int res; /* preparing the expression */ sprintf(buf, "%s = ", dataset_col_name(grace, i)); expr = copy_string(NULL, buf); expr = concat_strings(expr, formula[i]); /* evaluate the expression */ res = graal_parse_line(grace_get_graal(grace), expr, NULL); xfree(expr); if (res != RETURN_SUCCESS) { quark_free(pset); return RETURN_FAILURE; } } #if 0 XCFREE(t->data); t->length = 0; #endif update_set_lists(gr); return RETURN_SUCCESS; }
void generate_ground(Model *model, int chunk_x, int chunk_y, float detail) { PROFILE_BLOCK("Generate Ground"); int size_x = CHUNK_SIZE_X; int size_y = CHUNK_SIZE_Y; int offset_x = chunk_x * size_x; int offset_y = chunk_y * size_y; int width = size_x * detail + 1; int height = size_y * detail + 1; u32 vertices_count = width * height * 3; u32 normals_count = vertices_count; u32 colors_count = vertices_count; u32 indices_count = (width - 1) * (height - 1) * 6; Mesh mesh = {}; allocate_mesh(&mesh, vertices_count, normals_count, indices_count, 0, colors_count); u32 vertices_index = 0; u32 colors_index = 0; u32 normals_index = 0; u32 indices_index = 0; float radius = 0.0f; for (int x=0; x<width; x++) { for (int y=0; y<height; y++) { float x_coord = (float)(x) / detail; float y_coord = (float)(y) / detail; float value = get_terrain_height_at(x_coord + offset_x, y_coord + offset_y); mesh.data.vertices[vertices_index++] = x_coord; mesh.data.vertices[vertices_index++] = value; mesh.data.vertices[vertices_index++] = y_coord; vec3 color = vec3(0.4392f, 0.4588f, 0.3412f); if (value < 7.0f) { color = vec3(0.8118f, 0.5686f, 0.3804f); } mesh.data.colors[colors_index++] = color.r; mesh.data.colors[colors_index++] = color.g; mesh.data.colors[colors_index++] = color.b; // TODO(sedivy): calculate center float distance = glm::length(vec3(x_coord, value, y_coord)); if (distance > radius) { radius = distance; } mesh.data.normals[normals_index++] = 0.0f; mesh.data.normals[normals_index++] = 0.0f; mesh.data.normals[normals_index++] = 0.0f; } } for (int i=0; i<height - 1; i++) { for (int l=0; l<width - 1; l++) { mesh.data.indices[indices_index++] = (height * l + i + 0); mesh.data.indices[indices_index++] = (height * l + i + 1); mesh.data.indices[indices_index++] = (height * l + i + height); mesh.data.indices[indices_index++] = (height * l + i + height); mesh.data.indices[indices_index++] = (height * l + i + 1); mesh.data.indices[indices_index++] = (height * l + i + height + 1); } } for (u32 i=0; i<indices_count; i += 3) { int indices_a = mesh.data.indices[i + 0] * 3; int indices_b = mesh.data.indices[i + 1] * 3; int indices_c = mesh.data.indices[i + 2] * 3; vec3 v0 = vec3(mesh.data.vertices[indices_a + 0], mesh.data.vertices[indices_a + 1], mesh.data.vertices[indices_a + 2]); vec3 v1 = vec3(mesh.data.vertices[indices_b + 0], mesh.data.vertices[indices_b + 1], mesh.data.vertices[indices_b + 2]); vec3 v2 = vec3(mesh.data.vertices[indices_c + 0], mesh.data.vertices[indices_c + 1], mesh.data.vertices[indices_c + 2]); vec3 normal = glm::normalize(glm::cross(v2 - v0, v1 - v0)); mesh.data.normals[indices_a + 0] = -normal.x; mesh.data.normals[indices_a + 1] = -normal.y; mesh.data.normals[indices_a + 2] = -normal.z; mesh.data.normals[indices_b + 0] = -normal.x; mesh.data.normals[indices_b + 1] = -normal.y; mesh.data.normals[indices_b + 2] = -normal.z; mesh.data.normals[indices_c + 0] = -normal.x; mesh.data.normals[indices_c + 1] = -normal.y; mesh.data.normals[indices_c + 2] = -normal.z; } for (u32 i=0; i<normals_count / 3; i += 3) { float x = mesh.data.normals[i + 0]; float y = mesh.data.normals[i + 1]; float z = mesh.data.normals[i + 2]; vec3 normal = glm::normalize(vec3(x, y, z)); mesh.data.normals[i + 0] = normal.x; mesh.data.normals[i + 1] = normal.y; mesh.data.normals[i + 2] = normal.z; } model->id_name = allocate_string("chunk"); model->mesh = mesh; model->radius = radius; }