📄 mesh.c
字号:
cos_a = gf_cos(alpha); sin_a = spine_vec.z; sin_g = 0; if (NEAR_ZERO(cos_a) ) gamma = 0; else { Fixed __abs; gamma = gf_acos(gf_divfix(spine_vec.y, cos_a)); sin_g = gf_sin(gamma); __abs = gf_divfix(spine_vec.x, cos_a) + sin_g; if (ABS(__abs) > ABS(sin_g) ) gamma *= -1; } cos_g = gf_cos(gamma); sin_g = gf_sin(gamma); SCPi[0].yaxis.y = gf_mulfix(cos_a, sin_g); SCPi[0].yaxis.x = gf_mulfix(cos_a, cos_g); SCPi[0].yaxis.z = sin_a; SCPi[0].zaxis.y = -gf_mulfix(sin_a, sin_g); SCPi[0].zaxis.x = -gf_mulfix(sin_a, cos_g); SCPi[0].zaxis.z = cos_a; } } for (i=0; i<nb_spine; i++) { SCPs[i].xaxis = SCPi[0].xaxis; SCPs[i].yaxis = SCPi[0].yaxis; SCPs[i].zaxis = SCPi[0].zaxis; } } /*not colinear*/ else { assert(nb_scp<=nb_spine); /*now non-cap SCPs axis*/ for (i=1; i<nb_scp-1; i++) { /*get Y axis*/ gf_vec_diff(SCPi[i].yaxis, SCPi[i+1].pt, SCPi[i-1].pt); /*get Z axis*/ gf_vec_diff(v1, SCPi[i+1].pt, SCPi[i].pt); gf_vec_diff(v2, SCPi[i-1].pt, SCPi[i].pt); SCPi[i].zaxis = gf_vec_cross(v1, v2); } /*compute head and tail*/ if (spine_closed) { gf_vec_diff(SCPi[0].yaxis, SCPi[1].pt, SCPi[nb_scp-2].pt); gf_vec_diff(v1, SCPi[1].pt, SCPi[0].pt); gf_vec_diff(v2, SCPi[nb_scp-2].pt, SCPi[0].pt); SCPi[0].zaxis = gf_vec_cross(v1, v2); SCPi[nb_scp-1].yaxis = SCPi[0].yaxis; SCPi[nb_scp-1].zaxis = SCPi[0].zaxis; } else { gf_vec_diff(SCPi[0].yaxis, SCPi[1].pt, SCPi[0].pt); SCPi[0].zaxis = SCPi[1].zaxis; gf_vec_diff(SCPi[nb_scp-1].yaxis, SCPi[nb_scp-1].pt, SCPi[nb_scp-2].pt); SCPi[nb_scp-1].zaxis = SCPi[nb_scp-2].zaxis; } /*check orientation*/ for (i=1; i<nb_scp; i++) { Fixed res = gf_vec_dot(SCPi[i].zaxis, SCPi[i-1].zaxis); if (res<0) gf_vec_rev(SCPi[i].zaxis); } /*and assign SCPs*/ j=0; for (i=0; i<nb_scp; i++) { /*compute X, norm vectors*/ SCPi[i].xaxis = gf_vec_cross(SCPi[i].yaxis, SCPi[i].zaxis); gf_vec_norm(&SCPi[i].xaxis); gf_vec_norm(&SCPi[i].yaxis); gf_vec_norm(&SCPi[i].zaxis); /*assign SCPs*/ while (j<=SCPi[i].max_idx) { SCPs[j].xaxis = SCPi[i].xaxis; SCPs[j].yaxis = SCPi[i].yaxis; SCPs[j].zaxis = SCPi[i].zaxis; j++; } } } free(SCPi); SCPbegin = SCPs[0]; SCPend = SCPs[nb_spine-1]; r.x = r.q = r.z = 0; r.y = FIX_ONE; scale.x = scale.y = FIX_ONE; cur_spine = 0; /*insert all points of the extrusion*/ for (i=0; i<nb_spine; i++) { u32 cur_face_in_cross; SCP *curSCP; if (spine_closed && (i+1==nb_spine)) { curSCP = &SCPs[0]; do_close = 1; } else { curSCP = &SCPs[i]; do_close = 0; /*compute X*/ curSCP->xaxis = gf_vec_cross(curSCP->yaxis, curSCP->zaxis); gf_vec_norm(&curSCP->xaxis); gf_vec_norm(&curSCP->yaxis); gf_vec_norm(&curSCP->zaxis); if (spine_ori && (i<spine_ori->count)) r = spine_ori->vals[i]; if (spine_scale && (i<spine_scale->count)) scale = spine_scale->vals[i]; gf_mx_init(mx); gf_mx_add_rotation(&mx, r.q, r.x, r.y, r.z); gf_mx_apply_vec(&mx, &curSCP->xaxis); gf_mx_apply_vec(&mx, &curSCP->yaxis); gf_mx_apply_vec(&mx, &curSCP->zaxis); } vx.texcoords.y = gf_divfix(cur_spine, spine_len); cur_pts_in_cross = 0; cur_face_in_cross = 0; cur = 0; for (j=0; j<path->n_contours; j++) { Bool subpath_closed; nb_pts = 1+path->contours[j] - cur; cur_cross = 0; subpath_closed = 0; if ((path->points[cur].x==path->points[path->contours[j]].x) && (path->points[cur].y==path->points[path->contours[j]].y)) subpath_closed = 1; for (k=0; k<nb_pts; k++) { u32 pidx = k + cur_pts_in_cross + i*pts_per_cross; if (do_close) pidx = k + cur_pts_in_cross; v1.x = path->points[k+cur].x; v1.z = path->points[k+cur].y; if (tx_along_spine) { vx.texcoords.x = gf_divfix(cur_cross, cross_len); } else { vx.texcoords.x = gf_divfix(v1.x - min_cx, width_cx); vx.texcoords.y = gf_divfix(v1.z - min_cy, width_cy); } /*handle closed cross-section*/ if (subpath_closed && (k+1==nb_pts)) { pidx = cur_pts_in_cross + i*pts_per_cross; if (do_close) pidx = cur_pts_in_cross; v1.x = path->points[cur].x; v1.z = path->points[cur].y; } v1.x = gf_mulfix(v1.x, scale.x); v1.z = gf_mulfix(v1.z, scale.y); v1.y = 0; vx.pos.x = gf_mulfix(v1.x, curSCP->xaxis.x) + gf_mulfix(v1.y, curSCP->yaxis.x) + gf_mulfix(v1.z, curSCP->zaxis.x) + spine[i].x; vx.pos.y = gf_mulfix(v1.x, curSCP->xaxis.y) + gf_mulfix(v1.y, curSCP->yaxis.y) + gf_mulfix(v1.z, curSCP->zaxis.y) + spine[i].y; vx.pos.z = gf_mulfix(v1.x, curSCP->xaxis.z) + gf_mulfix(v1.y, curSCP->yaxis.z) + gf_mulfix(v1.z, curSCP->zaxis.z) + spine[i].z; /*in current spine*/ if (i+1<nb_spine) { /*current face*/ if (k<nb_pts-1) REGISTER_POINT_FACE(k + cur_face_in_cross + i*faces_per_cross); /*previous face*/ if (k) REGISTER_POINT_FACE(k-1 + cur_face_in_cross + i*faces_per_cross); } /*first spine*/ else if (smooth_normals && do_close) { if (k<nb_pts-1) { register_point_in_face(&faces_info[k + cur_face_in_cross], pidx); register_face_in_point(&pts_info[pidx], k + cur_face_in_cross); } /*previous face*/ if (k) { register_point_in_face(&faces_info[k-1 + cur_face_in_cross], pidx); register_face_in_point(&pts_info[pidx], k-1 + cur_face_in_cross); } } /*in previous spine*/ if (i) { /*face "below" face*/ if (k<nb_pts-1) REGISTER_POINT_FACE(k + cur_face_in_cross + (i-1)*faces_per_cross); /*previous face "below" face*/ if (k) REGISTER_POINT_FACE(k-1 + cur_face_in_cross + (i-1)*faces_per_cross); } if (k+1<nb_pts) { v1.z = 0; v1.x = path->points[k+1+cur].x - path->points[k+cur].x; v1.y = path->points[k+1+cur].y - path->points[k+cur].y; cur_cross += gf_vec_len(v1); } } cur_face_in_cross += nb_pts-1; cur_pts_in_cross += nb_pts; cur += nb_pts; } if (i+1<nb_spine) { gf_vec_diff(v1, spine[i+1], spine[i]); cur_spine += gf_vec_len(v1); } } /*generate triangles & normals*/ for (i=0; i<face_spines; i++) { mesh_set_triangle(faces[i], 0, 1, 3); mesh_set_triangle(faces[i], 0, 3, 2); gf_vec_diff(v1, faces[i]->vertices[1].pos, faces[i]->vertices[0].pos); gf_vec_diff(v2, faces[i]->vertices[3].pos, faces[i]->vertices[0].pos); n = gf_vec_cross(v1, v2); gf_vec_norm(&n); for (j=0; j<faces[i]->v_count; j++) { faces[i]->vertices[j].normal = n; if (smooth_normals) faces_info[i].nor = n; } } /*generate begin cap*/ if (begin_face) { scale.x = scale.y = FIX_ONE; if (spine_scale && spine_scale->count) scale = spine_scale->vals[0]; /*get first SCP after rotation*/ SCPbegin = SCPs[0]; vx.normal = SCPbegin.yaxis; gf_vec_norm(&vx.normal); convexity = gf_polygone2d_get_convexity(path->points, path->n_points); switch (convexity) { case GF_POLYGON_CONVEX_CCW: case GF_POLYGON_COMPLEX_CCW: gf_vec_rev(vx.normal); break; } if (smooth_normals) { faces_info[begin_face].nor = vx.normal; assert(gf_vec_len(vx.normal)); } cur_pts_in_cross = 0; cur = 0; for (i=0; i<path->n_contours; i++) { Bool subpath_closed = 0; nb_pts = 1 + path->contours[i] - cur; if ((path->points[cur].x==path->points[path->contours[i]].x) && (path->points[cur].y==path->points[path->contours[i]].y)) subpath_closed = 1; for (j=0; j<nb_pts; j++) { u32 pidx = j + (pts_per_cross-1-cur_pts_in_cross); v1.x = path->points[j+cur].x; v1.z = path->points[j+cur].y; vx.texcoords.x = gf_divfix(v1.x - min_cx, width_cx); vx.texcoords.y = gf_divfix(v1.z - min_cy, width_cy); /*handle closed cross-section*/ if (subpath_closed && (j+1==nb_pts)) { pidx = (pts_per_cross-1-cur_pts_in_cross); v1.x = path->points[cur].x; v1.z = path->points[cur].y; } v1.x = gf_mulfix(v1.x , scale.x); v1.z = gf_mulfix(v1.z , scale.y); v1.y = 0; vx.pos.x = gf_mulfix(v1.x, SCPbegin.xaxis.x) + gf_mulfix(v1.y, SCPbegin.yaxis.x) + gf_mulfix(v1.z, SCPbegin.zaxis.x) + spine[0].x; vx.pos.y = gf_mulfix(v1.x, SCPbegin.xaxis.y) + gf_mulfix(v1.y, SCPbegin.yaxis.y) + gf_mulfix(v1.z, SCPbegin.zaxis.y) + spine[0].y; vx.pos.z = gf_mulfix(v1.x, SCPbegin.xaxis.z) + gf_mulfix(v1.y, SCPbegin.yaxis.z) + gf_mulfix(v1.z, SCPbegin.zaxis.z) + spine[0].z; REGISTER_POINT_FACE(begin_face); } cur_pts_in_cross += nb_pts; cur += nb_pts; } } /*generate end cap*/ if (end_face) { scale.x = scale.y = FIX_ONE; if (spine_scale && (nb_spine-1<spine_scale->count)) scale = spine_scale->vals[nb_spine-1]; /*get last SCP after rotation*/ SCPend = SCPs[nb_spine-1]; vx.normal = SCPend.yaxis; gf_vec_norm(&vx.normal); convexity = gf_polygone2d_get_convexity(path->points, path->n_points); switch (convexity) { case GF_POLYGON_CONVEX_CCW: case GF_POLYGON_COMPLEX_CCW: gf_vec_rev(vx.normal); break; } if (smooth_normals) { faces_info[end_face].nor = vx.normal; assert(gf_vec_len(vx.normal)); } cur_pts_in_cross = 0; cur = 0; for (i=0; i<path->n_contours; i++) { Bool subpath_closed = 0; nb_pts = 1 + path->contours[i] - cur; if ((path->points[cur].x==path->points[path->contours[i]].x) && (path->points[cur].y==path->points[path->contours[i]].y)) subpath_closed = 1; for (j=0; j<nb_pts; j++) { u32 pidx = j + cur_pts_in_cross + (nb_spine-1)*pts_per_cross; v1.x = path->points[j+cur].x; v1.z = path->points[j+cur].y; vx.texcoords.x = gf_divfix(v1.x - min_cx, width_cx); vx.texcoords.y = gf_divfix(v1.z - min_cy, width_cy); /*handle closed cross-section*/ if (subpath_closed && (j+1==nb_pts)) { pidx = cur_pts_in_cross + (nb_spine-1)*pts_per_cross; v1.x = path->points[cur].x; v1.z = path->points[cur].y; } v1.x = gf_mulfix(v1.x, scale.x); v1.z = gf_mulfix(v1.z, scale.y); v1.y = 0; vx.pos.x = gf_mulfix(v1.x, SCPend.xaxis.x) + gf_mulfix(v1.y, SCPend.yaxis.x) + gf_mulfix(v1.z, SCPend.zaxis.x) + spine[nb_spine-1].x; vx.pos.y = gf_mulfix(v1.x, SCPend.xaxis.y) + gf_mulfix(v1.y, SCPend.yaxis.y) + gf_mulfix(v1.z, SCPend.zaxis.y) + spine[nb_spine-1].y; vx.pos.z = gf_mulfix(v1.x, SCPend.xaxis.z) + gf_mulfix(v1.y, SCPend.yaxis.z) + gf_mulfix(v1.z, SCPend.zaxis.z) + spine[nb_spine-1].z; REGISTER_POINT_FACE(end_face); } cur_pts_in_cross += nb_pts; cur += nb_pts; } } if (smooth_normals) { Fixed cosCrease; /*we only support 0->PI, whatever exceeds is smoothest*/ if (creaseAngle>GF_PI) cosCrease = -FIX_ONE; else cosCrease = gf_cos(creaseAngle); for (i=0; i<face_count; i++) { for (j=0; j<faces[i]->v_count; j++) { faces[i]->vertices[j].normal = smooth_face_normals(pts_info, pt_count, faces_info, face_count, j, i, cosCrease); } } if (faces_info) { for (i=0; i<face_count; i++) if (faces_info[i].idx) free(faces_info[i].idx); free(faces_info); } if (pts_info) { for (i=0; i<pt_count; i++) if (pts_info[i].faces) free(pts_info[i].faces); free(pts_info); } mesh->flags |= MESH_IS_SMOOTHED; } mesh->mesh_type = MESH_TRIANGLES; for (i=0; i<face_spines; i++) { if (faces[i]->v_count) { u32 init_idx; GF_Mesh *face = faces[i]; init_idx = mesh->v_count; /*quads only*/ mesh_set_vertex_vx(mesh, &face->vertices[0]); mesh_set_vertex_vx(mesh, &face->vertices[1]); mesh_set_vertex_vx(mesh, &face->vertices[2]); mesh_set_vertex_vx(mesh, &face->vertices[3]); mesh_set_triangle(mesh, init_idx + 0, init_idx + 1, init_idx + 3); mesh_set_triangle(mesh, init_idx + 0, init_idx + 3, init_idx + 2); } mesh_free(faces[i]); } if (begin_face) { if (path->n_contours>1) {#ifndef GPAC_USE_OGL_ES u32 *ptsPerFace = malloc(sizeof(u32)*path->n_contours); /*we reversed begin cap!!!*/ cur = 0; for (i=0; i<path->n_contours; i++) { nb_pts = 1+path->contours[i] - cur; cur+=nb_pts; ptsPerFace[i] = nb_pts; } TesselateFaceMeshComplex(mesh, faces[begin_face], path->n_contours, ptsPerFace); free(ptsPerFace);#endif } else { TesselateFaceMesh(mesh, faces[begin_face]); } mesh_free(faces[begin_face]); } if (end_face) { if (path->n_contours>1) {#ifndef GPAC_USE_OGL_ES u32 *ptsPerFace = malloc(sizeof(u32)*path->n_contours); cur = 0; for (i=0; i<path->n_contours; i++) { nb_pts = 1+path->contours[i] - cur; cur+=nb_pts; ptsPerFace[i] = nb_pts; } TesselateFaceMeshComplex(mesh, faces[end_face], path->n_contours, ptsPerFace); free(ptsPerFace);#endif } else { TesselateFaceMesh(mesh, faces[end_face]); } mesh_free(faces[end_face]); } free(faces); free(SCPs); /*FIXME: this is correct except we need to handle path cw/ccw - until then no possibility to get correct lighting*//* if (path->subpathlen && path->subpath[0]->closed && ((begin_face && end_face) || spine_closed)) mesh->flags |= MESH_IS_SOLID; else mesh->flags &= ~MESH_IS_SOLID;*/}void mesh_extrude_path_ext(GF_Mesh *mesh, GF_Path *path, MFVec3f *thespine, Fixed creaseAngle, Fixed min_cx, Fixed min_cy, Fixed width_cx, Fixed width_cy, Bool begin_cap, Bool end_cap, MFRotation *spine_ori, MFVec2f *spine_scale, Bool tx_along_spine){ mesh_extrude_path_intern(mesh, path, thespine, creaseAngle, min_cx, min_cy, width_cx, width_cy, begin_cap, end_cap, spine_ori, spine_scale, tx_along_spine);}void mesh_extrude_path(GF_Mesh *mesh, GF_Path *path, MFVec3f *thespine, Fixed creaseAngl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -