struct mesh *mesh_fabricate_planetary_ring(float ir, float or) { struct mesh *m; int i; m = malloc(sizeof(*m)); if (!m) return m; memset(m, 0, sizeof(*m)); m->nvertices = 360; m->ntriangles = m->nvertices; m->t = malloc(sizeof(*m->t) * m->ntriangles); if (!m->t) goto bail; memset(m->t, 0, sizeof(*m->t) * m->ntriangles); m->v = malloc(sizeof(*m->v) * m->nvertices); if (!m->v) goto bail; memset(m->v, 0, sizeof(*m->v) * m->nvertices); m->l = NULL; m->geometry_mode = MESH_GEOMETRY_TRIANGLES; /* set up vertices */ for (i = 0; i < m->nvertices; i += 2) { const float angle = ((2 * M_PI) * i) / m->nvertices; m->v[i].x = cos(angle) * ir; m->v[i].y = sin(angle) * ir; m->v[i].z = 0.0; m->v[i + 1].x = cos(angle) * or; m->v[i + 1].y = sin(angle) * or; m->v[i + 1].z = 0.0; } /* set up triangles */ for (i = 0; i < m->nvertices; i += 2) { struct vertex *v1, *v2, *v3, *v4; v1 = &m->v[i % m->nvertices]; v2 = &m->v[(i + 1) % m->nvertices]; v3 = &m->v[(i + 2) % m->nvertices]; v4 = &m->v[(i + 3) % m->nvertices]; m->t[i].v[0] = v3; m->t[i].v[1] = v2; m->t[i].v[2] = v1; m->t[i + 1].v[0] = v2; m->t[i + 1].v[1] = v3; m->t[i + 1].v[2] = v4; /* FIXME: set coplanar flags */ } m->radius = mesh_compute_radius(m); mesh_set_flat_shading_vertex_normals(m); mesh_uv_map_planetary_ring(m); return m; bail: mesh_free(m); return NULL; }
void mesh_scale(struct mesh *m, float scale) { int i; for (i = 0; i < m->nvertices; i++) { m->v[i].x *= scale; m->v[i].y *= scale; m->v[i].z *= scale; } m->radius = mesh_compute_radius(m); mesh_graph_dev_init(m); }
void mesh_derelict(struct mesh *m, float distortion) { int i; for (i = 0; i < m->nvertices; i++) { float dx, dy, dz; dx = (float) (snis_randn(1000) / 1000.0 - 0.5) * distortion; dy = (float) (snis_randn(1000) / 1000.0 - 0.5) * (distortion / 10.0) - 0.5; dz = (float) (snis_randn(1000) / 1000.0 - 0.5) * (distortion / 10.0) - 0.5; if (m->v[i].x < 0) { m->v[i].x = dx; m->v[i].y += dy; m->v[i].z += dz; } } m->radius = mesh_compute_radius(m); for (i = 0; i < m->nvertices; i++) m->v[i].x -= m->radius / 2.0; m->radius = mesh_compute_radius(m); mesh_set_flat_shading_vertex_normals(m); mesh_graph_dev_init(m); }
void mesh_distort_helper(struct mesh *m, float distortion) { int i; for (i = 0; i < m->nvertices; i++) { float dx, dy, dz; dx = (float) snis_randn(1000) / 1000.0 * distortion - 0.5; dy = (float) snis_randn(1000) / 1000.0 * distortion - 0.5; dz = (float) snis_randn(1000) / 1000.0 * distortion - 0.5; m->v[i].x += m->v[i].x * dx; m->v[i].y += m->v[i].y * dy; m->v[i].z += m->v[i].z * dz; } m->radius = mesh_compute_radius(m); mesh_set_flat_shading_vertex_normals(m); }
/* See: http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html */ struct mesh *mesh_unit_icosohedron(void) { const double tau = (1.0 + sqrt(5.0)) / 2.0; const double scale = 1.0 / sqrt(1.0 + tau * tau); struct mesh *m; m = malloc(sizeof(*m)); if (!m) return m; memset(m, 0, sizeof(*m)); m->nvertices = 12; m->ntriangles = 20; m->t = malloc(sizeof(*m->t) * m->ntriangles); if (!m->t) goto bail; memset(m->t, 0, sizeof(*m->t) * m->ntriangles); m->v = malloc(sizeof(*m->v) * m->nvertices); if (!m->v) goto bail; memset(m->v, 0, sizeof(*m->v) * m->nvertices); m->tex = 0; /* m->tex = malloc(sizeof(*m->tex) * m->ntriangles * 3); if (!m->tex) goto bail; memset(m->tex, 0, sizeof(*m->tex) * m->ntriangles * 3); */ m->l = NULL; m->geometry_mode = MESH_GEOMETRY_TRIANGLES; m->v[0].x = scale * -1.0; m->v[0].y = scale * tau; m->v[0].z = scale * 0.0; m->v[1].x = scale * 1.0; m->v[1].y = scale * tau; m->v[1].z = scale * 0.0; m->v[2].x = scale * -1.0; m->v[2].y = scale * -tau; m->v[2].z = scale * 0.0; m->v[3].x = scale * 1.0; m->v[3].y = scale * -tau; m->v[3].z = scale * 0.0; m->v[4].x = scale * 0.0; m->v[4].y = scale * -1.0; m->v[4].z = scale * tau; m->v[5].x = scale * 0.0; m->v[5].y = scale * 1.0; m->v[5].z = scale * tau; m->v[6].x = scale * 0.0; m->v[6].y = scale * -1.0; m->v[6].z = scale * -tau; m->v[7].x = scale * 0.0; m->v[7].y = scale * 1.0; m->v[7].z = scale * -tau; m->v[8].x = scale * tau; m->v[8].y = scale * 0.0; m->v[8].z = scale * -1.0; m->v[9].x = scale * tau; m->v[9].y = scale * 0.0; m->v[9].z = scale * 1.0; m->v[10].x = scale * -tau; m->v[10].y = scale * 0.0; m->v[10].z = scale * -1.0; m->v[11].x = scale * -tau; m->v[11].y = scale * 0.0; m->v[11].z = scale * 1.0; m->t[0].v[0] = &m->v[0]; m->t[0].v[1] = &m->v[11]; m->t[0].v[2] = &m->v[5]; m->t[1].v[0] = &m->v[0]; m->t[1].v[1] = &m->v[5]; m->t[1].v[2] = &m->v[1]; m->t[2].v[0] = &m->v[0]; m->t[2].v[1] = &m->v[1]; m->t[2].v[2] = &m->v[7]; m->t[3].v[0] = &m->v[0]; m->t[3].v[1] = &m->v[7]; m->t[3].v[2] = &m->v[10]; m->t[4].v[0] = &m->v[0]; m->t[4].v[1] = &m->v[10]; m->t[4].v[2] = &m->v[11]; m->t[5].v[0] = &m->v[1]; m->t[5].v[1] = &m->v[5]; m->t[5].v[2] = &m->v[9]; m->t[6].v[0] = &m->v[5]; m->t[6].v[1] = &m->v[11]; m->t[6].v[2] = &m->v[4]; m->t[7].v[0] = &m->v[11]; m->t[7].v[1] = &m->v[10]; m->t[7].v[2] = &m->v[2]; m->t[8].v[0] = &m->v[10]; m->t[8].v[1] = &m->v[7]; m->t[8].v[2] = &m->v[6]; m->t[9].v[0] = &m->v[7]; m->t[9].v[1] = &m->v[1]; m->t[9].v[2] = &m->v[8]; m->t[10].v[0] = &m->v[3]; m->t[10].v[1] = &m->v[9]; m->t[10].v[2] = &m->v[4]; m->t[11].v[0] = &m->v[3]; m->t[11].v[1] = &m->v[4]; m->t[11].v[2] = &m->v[2]; m->t[12].v[0] = &m->v[3]; m->t[12].v[1] = &m->v[2]; m->t[12].v[2] = &m->v[6]; m->t[13].v[0] = &m->v[3]; m->t[13].v[1] = &m->v[6]; m->t[13].v[2] = &m->v[8]; m->t[14].v[0] = &m->v[3]; m->t[14].v[1] = &m->v[8]; m->t[14].v[2] = &m->v[9]; m->t[15].v[0] = &m->v[4]; m->t[15].v[1] = &m->v[9]; m->t[15].v[2] = &m->v[5]; m->t[16].v[0] = &m->v[2]; m->t[16].v[1] = &m->v[4]; m->t[16].v[2] = &m->v[11]; m->t[17].v[0] = &m->v[6]; m->t[17].v[1] = &m->v[2]; m->t[17].v[2] = &m->v[10]; m->t[18].v[0] = &m->v[8]; m->t[18].v[1] = &m->v[6]; m->t[18].v[2] = &m->v[7]; m->t[19].v[0] = &m->v[9]; m->t[19].v[1] = &m->v[8]; m->t[19].v[2] = &m->v[1]; m->radius = mesh_compute_radius(m); mesh_set_flat_shading_vertex_normals(m); mesh_graph_dev_init(m); return m; bail: mesh_free(m); return NULL; }
struct mesh *mesh_fabricate_billboard(float cx, float cy, float width, float height) { struct mesh *m; m = malloc(sizeof(*m)); if (!m) return m; memset(m, 0, sizeof(*m)); m->nvertices = 4; m->ntriangles = 2; m->t = malloc(sizeof(*m->t) * m->ntriangles); if (!m->t) goto bail; memset(m->t, 0, sizeof(*m->t) * m->ntriangles); m->v = malloc(sizeof(*m->v) * m->nvertices); if (!m->v) goto bail; memset(m->v, 0, sizeof(*m->v) * m->nvertices); m->tex = malloc(sizeof(*m->tex) * m->ntriangles * 3); if (!m->tex) goto bail; memset(m->tex, 0, sizeof(*m->tex) * m->ntriangles * 3); m->l = NULL; m->geometry_mode = MESH_GEOMETRY_TRIANGLES; m->v[0].x = -width / 2.0f + cx; m->v[0].y = height / 2.0f + cy; m->v[0].z = 0; m->v[1].x = width / 2.0f + cx; m->v[1].y = height / 2.0f + cy; m->v[1].z = 0; m->v[2].x = width / 2.0f + cx; m->v[2].y = -height / 2.0f + cy; m->v[2].z = 0; m->v[3].x = -width / 2.0f + cx; m->v[3].y = -height / 2.0f + cy; m->v[3].z = 0; m->t[0].v[0] = &m->v[0]; m->t[0].v[1] = &m->v[2]; m->t[0].v[2] = &m->v[1]; m->t[0].flag = TRIANGLE_0_1_COPLANAR; mesh_set_triangle_texture_coords(m, 0, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f); m->t[1].v[0] = &m->v[0]; m->t[1].v[1] = &m->v[3]; m->t[1].v[2] = &m->v[2]; m->t[1].flag = TRIANGLE_0_2_COPLANAR; mesh_set_triangle_texture_coords(m, 1, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f); m->radius = mesh_compute_radius(m); mesh_set_flat_shading_vertex_normals(m); mesh_graph_dev_init(m); return m; bail: mesh_free(m); return NULL; }
/* mesh_fabricate_crossbeam fabricates a mesh like so, out of 8 triangles: * 0 * |\ * | \ * | \ * 4______| \__5 * \ \ \ \ * \ \ |3 \ * \ \ | \ * \ 1 \ | \ * \_____\|_____\6 * 7 \ | * \ | * \ | * \| * 2 * centered on origin, length axis parallel to x axis. * length is the distance betwee 0 and 3, above, and * radius is the distance between the center of the cross * beam and 2,6,7,3 and 0,4,5,1. * * 8 triangles are needed because we need to prevent backface * culling, so we wind one set of tris one way, and the other, * the other. */ struct mesh *mesh_fabricate_crossbeam(float length, float radius) { struct mesh *m; m = malloc(sizeof(*m)); if (!m) return m; memset(m, 0, sizeof(*m)); m->nvertices = 8; m->ntriangles = 8; m->t = malloc(sizeof(*m->t) * m->ntriangles); if (!m->t) goto bail; memset(m->t, 0, sizeof(*m->t) * m->ntriangles); m->v = malloc(sizeof(*m->v) * m->nvertices); if (!m->v) goto bail; memset(m->v, 0, sizeof(*m->v) * m->nvertices); m->tex = malloc(sizeof(*m->tex) * m->ntriangles * 3); if (!m->tex) goto bail; memset(m->tex, 0, sizeof(*m->tex) * m->ntriangles * 3); m->l = NULL; m->geometry_mode = MESH_GEOMETRY_TRIANGLES; m->v[0].x = -length / 2.0f; m->v[0].y = radius; m->v[0].z = 0.0f; m->v[1].x = -length / 2.0f; m->v[1].y = -radius; m->v[1].z = 0.0f; m->v[2].x = length / 2.0f; m->v[2].y = -radius; m->v[2].z = 0.0f; m->v[3].x = length / 2.0f; m->v[3].y = radius; m->v[3].z = 0.0f; m->v[4].x = -length / 2.0f; m->v[4].y = 0.0f; m->v[4].z = radius; m->v[5].x = -length / 2.0f; m->v[5].y = 0.0f; m->v[5].z = -radius; m->v[6].x = length / 2.0f; m->v[6].y = 0.0f; m->v[6].z = -radius; m->v[7].x = length / 2.0f; m->v[7].y = 0.0f; m->v[7].z = radius; m->t[0].v[0] = &m->v[0]; m->t[0].v[1] = &m->v[1]; m->t[0].v[2] = &m->v[2]; mesh_set_triangle_texture_coords(m, 0, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); m->t[1].v[0] = &m->v[2]; m->t[1].v[1] = &m->v[3]; m->t[1].v[2] = &m->v[0]; mesh_set_triangle_texture_coords(m, 1, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f); m->t[2].v[0] = &m->v[4]; m->t[2].v[1] = &m->v[5]; m->t[2].v[2] = &m->v[6]; mesh_set_triangle_texture_coords(m, 2, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f); m->t[3].v[0] = &m->v[6]; m->t[3].v[1] = &m->v[7]; m->t[3].v[2] = &m->v[4]; mesh_set_triangle_texture_coords(m, 3, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f); m->t[4].v[0] = &m->v[2]; m->t[4].v[1] = &m->v[1]; m->t[4].v[2] = &m->v[0]; mesh_set_triangle_texture_coords(m, 4, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f); m->t[5].v[0] = &m->v[0]; m->t[5].v[1] = &m->v[3]; m->t[5].v[2] = &m->v[2]; mesh_set_triangle_texture_coords(m, 5, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f); m->t[6].v[0] = &m->v[6]; m->t[6].v[1] = &m->v[5]; m->t[6].v[2] = &m->v[4]; mesh_set_triangle_texture_coords(m, 6, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); m->t[7].v[0] = &m->v[4]; m->t[7].v[1] = &m->v[7]; m->t[7].v[2] = &m->v[6]; mesh_set_triangle_texture_coords(m, 7, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f); mesh_compute_radius(m); mesh_set_flat_shading_vertex_normals(m); mesh_graph_dev_init(m); return m; bail: mesh_free(m); return NULL; }
/* fabricate a tube of length h, radius r, with nfaces, parallel to x axis */ struct mesh *mesh_tube(float h, float r, float nfaces) { struct mesh *m; int ntris = nfaces * 2; int nvertices = nfaces * 2; int i, j; float angle, da; float l = h / 2.0; m = allocate_mesh_for_copy(ntris, nvertices, 0, 1); if (!m) return m; m->geometry_mode = MESH_GEOMETRY_TRIANGLES; da = 2 * M_PI / (float) nfaces; angle = 0.0; for (i = 0; i < nvertices; i += 2) { m->v[i].x = -l; m->v[i].y = r * cos(angle); m->v[i].z = r * -sin(angle); m->v[i + 1].x = l; m->v[i + 1].y = m->v[i].y; m->v[i + 1].z = m->v[i].z; angle += da; } m->nvertices = nvertices; for (i = 0; i < ntris; i += 2) { m->t[i].v[2] = &m->v[i % nvertices]; m->t[i].v[1] = &m->v[(i + 1) % nvertices]; m->t[i].v[0] = &m->v[(i + 2) % nvertices]; m->t[i + 1].v[2] = &m->v[(i + 2) % nvertices]; m->t[i + 1].v[1] = &m->v[(i + 1) % nvertices]; m->t[i + 1].v[0] = &m->v[(i + 3) % nvertices]; } m->ntriangles = ntris; for (i = 0; i < ntris; i++) { union vec3 normal; normal = compute_triangle_normal(&m->t[i]); m->t[i].n.x = normal.v.x; m->t[i].n.y = normal.v.y; m->t[i].n.z = normal.v.z; for (j = 0; j < 3; j++) { union vec3 normal = { { 0, -m->t[i].v[j]->y, -m->t[i].v[j]->z } }; vec3_normalize_self(&normal); m->t[i].vnormal[j].x = normal.v.x; m->t[i].vnormal[j].y = normal.v.y; m->t[i].vnormal[j].z = normal.v.z; } } mesh_set_flat_shading_vertex_normals(m); for (i = 0; i < ntris; i += 2) { mesh_set_triangle_texture_coords(m, i, 0.0, (float) ((int) ((i + 2) / 2)) * 1.0 / (float) nfaces, 1.0, (float) ((int) (i / 2)) / (float) nfaces, 0.0, (float) ((int) (i / 2)) / (float) nfaces); mesh_set_triangle_texture_coords(m, i + 1, 1.0, (float) ((int) ((i + 2) / 2)) / (float) nfaces, 1.0, (float) ((int) (i / 2)) / (float) nfaces, 0.0, (float) ((int) ((i + 2) / 2)) / (float) nfaces); } m->nlines = 0; m->radius = mesh_compute_radius(m); mesh_graph_dev_init(m); return m; }