📄 mesh.c
字号:
if (top) { Fixed aincr = GF_2PI / nfacets; Fixed angle = GF_PI + aincr; mesh_set_vertex(mesh, 0, height/2, 0, 0, FIX_ONE, 0, FIX_ONE/2, FIX_ONE/2); c_idx = mesh->v_count-1; for (i=nfacets; i>0; --i, angle += aincr) { mesh_set_vertex(mesh, coords[i - 1].x, coords[i - 1].y, coords[i - 1].z, 0, FIX_ONE, 0, (FIX_ONE + gf_sin(angle))/2, FIX_ONE - (FIX_ONE + gf_cos(angle))/2); if (i) mesh_set_triangle(mesh, c_idx, mesh->v_count-2, mesh->v_count-1); } mesh_set_vertex(mesh, coords[nfacets - 1].x, coords[nfacets - 1].y, coords[nfacets - 1].z, 0, FIX_ONE, 0, (FIX_ONE + gf_sin(angle))/2, FIX_ONE - (FIX_ONE + gf_cos(angle))/2); mesh_set_triangle(mesh, c_idx, mesh->v_count-2, mesh->v_count-1); } free(texcoords); free(coords); if (top && bottom && side) mesh->flags |= MESH_IS_SOLID; mesh->bounds.min_edge.x = mesh->bounds.min_edge.z = -radius; mesh->bounds.max_edge.x = mesh->bounds.max_edge.z = radius; mesh->bounds.max_edge.y = (side || (top && bottom)) ? height/2 : 0; mesh->bounds.min_edge.y = -mesh->bounds.max_edge.y; gf_bbox_refresh(&mesh->bounds); gf_mesh_build_aabbtree(mesh);}#define CONE_SUBDIV 24void mesh_new_cone(GF_Mesh *mesh, Fixed height, Fixed radius, Bool bottom, Bool side, Bool low_res){ u32 nfacets, i, c_idx; SFVec3f *coords; SFVec2f *texcoords; mesh_reset(mesh); if (!bottom && !side) return; nfacets = CONE_SUBDIV; if (low_res) nfacets /= HIGH_SPEED_RATIO; coords = (SFVec3f*)malloc(sizeof(SFVec3f) * nfacets); texcoords = (SFVec2f*)malloc(sizeof(SFVec2f) * nfacets); compute_cylinder(height, radius, nfacets, coords, texcoords); if (side) { Fixed Ny = gf_muldiv(radius, radius, height); for (i = 0; i < nfacets; ++i) { /*top*/ mesh_set_vertex(mesh, 0, coords[i].y, 0, coords[i].x, Ny, coords[i].z, texcoords[i].x, FIX_ONE); /*base*/ mesh_set_vertex(mesh, coords[i].x, -1*coords[i].y, coords[i].z, coords[i].x, Ny, coords[i].z, texcoords[i].x, 0); if (i) { mesh_set_triangle(mesh, mesh->v_count-4, mesh->v_count-1, mesh->v_count-3); } } /*top*/ mesh_set_vertex(mesh, 0, coords[0].y, 0, coords[0].x, Ny, coords[0].z, texcoords[0].x - FIX_ONE, FIX_ONE); /*base*/ mesh_set_vertex(mesh, coords[0].x, -1*coords[0].y, coords[0].z, coords[0].x, Ny, coords[0].z, texcoords[0].x - FIX_ONE, 0); mesh_set_triangle(mesh, mesh->v_count-4, mesh->v_count-1, mesh->v_count-3); } if (bottom) { Fixed angle = 0; Fixed aincr = GF_2PI / nfacets; mesh_set_vertex(mesh, 0, -height/2, 0, 0, -FIX_ONE, 0, FIX_ONE/2, FIX_ONE/2); c_idx = mesh->v_count - 1; for (i=0; i<nfacets; ++i, angle += aincr) { mesh_set_vertex(mesh, coords[i].x, -1*coords[i].y, coords[i].z, 0, -FIX_ONE, 0, (FIX_ONE + gf_sin(angle))/2, FIX_ONE - (FIX_ONE + gf_cos(angle))/2); if (i) mesh_set_triangle(mesh, c_idx, mesh->v_count-2, mesh->v_count-1); } mesh_set_vertex(mesh, coords[0].x, -1*coords[0].y, coords[0].z, 0, -FIX_ONE, 0, (FIX_ONE + gf_sin(angle))/2, FIX_ONE - (FIX_ONE + gf_cos(angle))/2); mesh_set_triangle(mesh, c_idx, mesh->v_count-2, mesh->v_count-1); } free(texcoords); free(coords); if (bottom && side) mesh->flags |= MESH_IS_SOLID; mesh->bounds.min_edge.x = mesh->bounds.min_edge.z = -radius; mesh->bounds.max_edge.x = mesh->bounds.max_edge.z = radius; mesh->bounds.max_edge.y = height/2; mesh->bounds.min_edge.y = -mesh->bounds.max_edge.y; gf_bbox_refresh(&mesh->bounds); gf_mesh_build_aabbtree(mesh);}void compute_sphere(Fixed radius, SFVec3f *coords, SFVec2f *texcoords, u32 num_steps){ Fixed r, angle, x, y, z; u32 i, j; for (i=0; i<num_steps; i++) { angle = (i * GF_PI / (num_steps-1) ) - GF_PI2; y = gf_sin(angle); r = gf_sqrt(FIX_ONE - gf_mulfix(y, y)); for (j = 0; j < num_steps; j++) { angle = GF_2PI * j / num_steps - GF_PI2; x = gf_mulfix(gf_cos(angle), r); z = gf_mulfix(gf_sin(angle), r); coords[i * num_steps + j].x = gf_mulfix(radius, x); coords[i * num_steps + j].y = gf_mulfix(radius, y); coords[i * num_steps + j].z = gf_mulfix(radius, z); texcoords[i * num_steps + j].x = FIX_ONE - (j+1)*FIX_ONE/num_steps; texcoords[i * num_steps + j].y = i*FIX_ONE/num_steps; } }}#define SPHERE_SUBDIV 12void mesh_new_sphere(GF_Mesh *mesh, Fixed radius, Bool low_res){ u32 i, j, num_steps, npts; SFVec3f *coords; SFVec2f *texcoords; num_steps = SPHERE_SUBDIV; if (low_res) num_steps /= 2; npts = num_steps * num_steps; coords = (SFVec3f*)malloc(sizeof(SFVec3f)*npts); texcoords = (SFVec2f*)malloc(sizeof(SFVec2f)*npts); compute_sphere(radius, coords, texcoords, num_steps); for (i=0; i<num_steps-1; i++) { u32 n = i * num_steps; for (j=0; j<num_steps; j++) { mesh_set_vertex(mesh, coords[n + j + num_steps].x, coords[n + j + num_steps].y, coords[n + j + num_steps].z, coords[n + j + num_steps].x, coords[n + j + num_steps].y, coords[n + j + num_steps].z, texcoords[n + j + num_steps].x, texcoords[n + j + num_steps].y); mesh_set_vertex(mesh, coords[n + j].x, coords[n + j].y, coords[n + j].z, coords[n + j].x, coords[n + j].y, coords[n + j].z, texcoords[n + j].x, texcoords[n + j].y); if (j) { mesh_set_triangle(mesh, mesh->v_count-3, mesh->v_count-4, mesh->v_count-2); mesh_set_triangle(mesh, mesh->v_count-3, mesh->v_count-2, mesh->v_count-1); } } mesh_set_vertex(mesh, coords[n + num_steps].x, coords[n + num_steps].y, coords[n + num_steps].z, coords[n + num_steps].x, coords[n + num_steps].y, coords[n + num_steps].z, 0/*FIX_ONE*/, texcoords[n + num_steps].y); mesh_set_vertex(mesh, coords[n].x, coords[n].y, coords[n].z, coords[n].x, coords[n].y, coords[n].z, 0/*FIX_ONE*/, texcoords[n].y); mesh_set_triangle(mesh, mesh->v_count-3, mesh->v_count-4, mesh->v_count-2); mesh_set_triangle(mesh, mesh->v_count-3, mesh->v_count-2, mesh->v_count-1); } free(coords); free(texcoords); mesh->flags |= MESH_IS_SOLID; mesh->bounds.min_edge.x = mesh->bounds.min_edge.y = mesh->bounds.min_edge.z = -radius; mesh->bounds.max_edge.x = mesh->bounds.max_edge.y = mesh->bounds.max_edge.z = radius; gf_bbox_refresh(&mesh->bounds); if (radius != FIX_ONE) gf_mesh_build_aabbtree(mesh);}void mesh_new_rectangle(GF_Mesh *mesh, SFVec2f size){ Fixed hx = size.x / 2; Fixed hy = size.y / 2; mesh_reset(mesh); mesh_set_vertex(mesh, -hx, -hy, 0, 0, 0, FIX_ONE, 0, 0); mesh_set_vertex(mesh, hx, -hy, 0, 0, 0, FIX_ONE, FIX_ONE, 0); mesh_set_vertex(mesh, hx, hy, 0, 0, 0, FIX_ONE, FIX_ONE, FIX_ONE); mesh_set_vertex(mesh, -hx, hy, 0, 0, 0, FIX_ONE, 0, FIX_ONE); mesh_set_triangle(mesh, 0, 1, 2); mesh_set_triangle(mesh, 0, 2, 3); mesh->flags |= MESH_IS_2D; mesh->bounds.min_edge.x = -hx; mesh->bounds.min_edge.y = -hy; mesh->bounds.min_edge.z = 0; mesh->bounds.max_edge.x = hx; mesh->bounds.max_edge.y = hy; mesh->bounds.max_edge.z = 0; gf_bbox_refresh(&mesh->bounds);}#define ELLIPSE_SUBDIV 32void mesh_new_ellipse(GF_Mesh *mesh, Fixed a_dia, Fixed b_dia, Bool low_res){ Fixed step, cur, end, cosa, sina; a_dia /= 2; b_dia /= 2; /*no begin/end draw since we always use generic 2D node drawing methods*/ end = GF_2PI; step = end / ELLIPSE_SUBDIV; if (low_res) step *= HIGH_SPEED_RATIO; mesh_reset(mesh); /*center*/ mesh_set_vertex(mesh, 0, 0, 0, 0, 0, FIX_ONE, FIX_ONE/2, FIX_ONE/2); for (cur=0; cur<end; cur += step) { cosa = gf_cos(cur); sina = gf_sin(cur); mesh_set_vertex(mesh, gf_mulfix(a_dia, cosa), gf_mulfix(b_dia, sina), 0, 0, 0, FIX_ONE, (FIX_ONE + cosa)/2, (FIX_ONE + sina)/2); if (cur) mesh_set_triangle(mesh, 0, mesh->v_count-2, mesh->v_count-1); } mesh_set_vertex(mesh, a_dia, 0, 0, 0, 0, FIX_ONE, FIX_ONE, FIX_ONE/2); mesh_set_triangle(mesh, 0, mesh->v_count-2, mesh->v_count-1); mesh->flags |= MESH_IS_2D; mesh->bounds.min_edge.x = -a_dia; mesh->bounds.min_edge.y = -b_dia; mesh->bounds.min_edge.z = 0; mesh->bounds.max_edge.x = a_dia; mesh->bounds.max_edge.y = b_dia; mesh->bounds.max_edge.z = 0; gf_bbox_refresh(&mesh->bounds);}void mesh_from_path_intern(GF_Mesh *mesh, GF_Path *path, Bool make_ccw){ u32 i, nbPts; Fixed w, h; GF_Rect bounds; Bool isCW = 0; gf_path_flatten(path); gf_path_get_bounds(path, &bounds); mesh_reset(mesh); if (path->n_contours==1) { u32 type = gf_polygone2d_get_convexity(path->points, path->n_points); switch (type) { /*degenrated polygon - skip*/ case GF_POLYGON_CONVEX_LINE: return; case GF_POLYGON_CONVEX_CW: isCW = make_ccw; case GF_POLYGON_CONVEX_CCW: w = bounds.width; h = bounds.height; /*add all vertices*/ for (i=0; i<path->n_points-1; i++) { GF_Point2D pt = path->points[i]; mesh_set_vertex(mesh, pt.x, pt.y, 0, 0, 0, FIX_ONE, gf_divfix(pt.x - bounds.x, w), gf_divfix(bounds.y - pt.y, h)); } nbPts = path->n_points - 1; /*take care of already closed path*/ if ( (path->points[i].x != path->points[0].x) || (path->points[i].y != path->points[0].y)) { GF_Point2D pt = path->points[i]; mesh_set_vertex(mesh, pt.x, pt.y, 0, 0, 0, FIX_ONE, gf_divfix(pt.x - bounds.x, w), gf_divfix(bounds.y - pt.y, h)); nbPts = path->n_points; } /*make it CCW*/ for (i=1; i<nbPts-1; i++) { if (isCW) { mesh_set_triangle(mesh, 0, nbPts-i, nbPts-i-1); } else { mesh_set_triangle(mesh, 0, i, i+1); } } mesh->bounds.min_edge.x = bounds.x; mesh->bounds.min_edge.y = bounds.y-bounds.height; mesh->bounds.min_edge.z = 0; mesh->bounds.max_edge.x = bounds.x+bounds.width; mesh->bounds.max_edge.y = bounds.y; mesh->bounds.max_edge.z = 0; gf_bbox_refresh(&mesh->bounds); return; default: break; } } /*we need to tesselate the path*/#ifndef GPAC_USE_OGL_ES TesselatePath(mesh, path, 0);#endif}void mesh_from_path(GF_Mesh *mesh, GF_Path *path){ mesh_from_path_intern(mesh, path, 1);}void mesh_get_outline(GF_Mesh *mesh, GF_Path *path){ u32 i, j, cur, nb_pts; mesh_reset(mesh); mesh->mesh_type = MESH_LINESET; mesh->flags |= (MESH_IS_2D | MESH_NO_TEXTURE); gf_path_flatten(path); cur = 0; for (i=0; i<path->n_contours; i++) { nb_pts = 1+path->contours[i] - cur; for (j=0; j<nb_pts; j++) { GF_Point2D pt = path->points[j+cur]; if (j) mesh_set_line(mesh, mesh->v_count-1, mesh->v_count); mesh_set_vertex(mesh, pt.x, pt.y, 0, 0, 0, FIX_ONE, 0, 0); } cur += nb_pts; } mesh_update_bounds(mesh);}#define COL_TO_RGBA(res, col) { res.red = col.red; res.green = col.green; res.blue = col.blue; res.alpha = FIX_ONE; }#define MESH_GET_COL(thecol, index) {\ if (colorRGB && ((u32) index < colorRGB->color.count) ) COL_TO_RGBA(thecol, colorRGB->color.vals[index]) \ else if (colorRGBA && (u32) index < colorRGBA->color.count) thecol = colorRGBA->color.vals[index]; \ } \void mesh_new_ils(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex, GF_Node *__color, MFInt32 *colorIndex, Bool colorPerVertex, Bool do_close){ u32 i, n, count, c_count, col_count; u32 index; u32 first_idx, last_idx; Bool move_to; SFVec3f pt; SFColorRGBA colRGBA; Bool has_color, has_coord; M_Coordinate2D *coord2D = (M_Coordinate2D*) __coord; M_Coordinate *coord = (M_Coordinate*) __coord; M_Color *colorRGB = (M_Color *) __color; X_ColorRGBA *colorRGBA = (X_ColorRGBA *) __color; if (__coord && (gf_node_get_tag(__coord) == TAG_MPEG4_Coordinate2D)) { coord = NULL; } else { coord2D = NULL; } colRGBA.red = colRGBA.green = colRGBA.blue = colRGBA.alpha = 0; if (!coord2D && !coord) return; c_count = coord2D ? coord2D->point.count : coord->point.count; if (!c_count) return; count = coordIndex->count; has_coord = count ? 1 : 0; if (!has_coord) count = c_count; if (!colorIndex->vals) colorIndex = coordIndex; col_count = colorIndex->count ? colorIndex->count : c_count; /*not enough color indices, use coord ones*/ if (colorPerVertex && (col_count<count) ) { colorIndex = coordIndex; col_count = count; } has_color = 0; if (__color) { if (gf_node_get_tag(__color)==TAG_X3D_ColorRGBA) { colorRGB = NULL; has_color = (colorRGBA->color.count) ? 1 : 0; } else { colorRGBA = NULL; has_color = (colorRGB->color.count) ? 1 : 0; } } mesh_reset(mesh); mesh->mesh_type = MESH_LINESET; if (has_color) mesh->flags |= MESH_HAS_COLOR; n = 0; if (has_color && !colorPerVertex) { index = colorIndex->count ? colorIndex->vals[0] : 0; if ((u32) index < col_count) MESH_GET_COL(colRGBA, index); } move_to = 1; first_idx = last_idx = 0; for (i=0; i<count; i++) { if (has_coord && coordIndex->vals[i] == -1) { /*close color per vertex*/ if (!move_to && do_close && !gf_vec_equal(mesh->vertices[first_idx].pos, mesh->vertices[last_idx].pos) ) { mesh_set_line(mesh, last_idx, first_idx); } move_to = 1; n++; if (has_color && !colorPerVertex) { if (n<colorIndex->count) index = colorIndex->vals[n]; else if (n<col_count) index = n; else index = 0; MESH_GET_COL(colRGBA, index); } } else { if (has_color && colorPerVertex) { if (i<colorIndex->count) index = colorIndex->vals[i]; else if (i<col_count) index = i; else index=0; MESH_GET_COL(colRGBA, index); } if (has_coord) index = coordIndex->vals[i]; else index = i; if (index < c_count) { if (coord2D) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -