📄 mesh.c
字号:
pt.x = coord2D->point.vals[index].x; pt.y = coord2D->point.vals[index].y; pt.z = 0; } else { pt = coord->point.vals[index]; } mesh_set_point(mesh, pt.x, pt.y, pt.z, colRGBA); last_idx = mesh->v_count - 1; if (move_to) { first_idx = last_idx; move_to = 0; } else { mesh_set_line(mesh, last_idx-1, last_idx); } } } } /*close color per vertex*/ if (do_close && !gf_vec_equal(mesh->vertices[first_idx].pos, mesh->vertices[last_idx].pos) ) { mesh_set_line(mesh, last_idx, first_idx); } if (coord2D) mesh->flags |= MESH_IS_2D; if (colorRGBA) mesh->flags |= MESH_HAS_ALPHA; mesh_update_bounds(mesh);}void mesh_new_ps(GF_Mesh *mesh, GF_Node *__coord, GF_Node *__color){ u32 c_count, i; Bool has_color; SFVec3f pt; SFColorRGBA colRGBA; 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; } if (!coord2D && !coord) return; c_count = coord2D ? coord2D->point.count : coord->point.count; if (!c_count) return; mesh_reset(mesh); mesh->mesh_type = MESH_POINTSET; 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; } } if (has_color) mesh->flags |= MESH_HAS_COLOR; colRGBA.red = colRGBA.green = colRGBA.blue = colRGBA.alpha = FIX_ONE; for (i=0; i<c_count; ++i) { if (has_color) MESH_GET_COL(colRGBA, i); if (coord2D) { pt.x = coord2D->point.vals[i].x; pt.y = coord2D->point.vals[i].y; pt.z = 0; } else { pt = coord->point.vals[i]; } mesh_set_point(mesh, pt.x, pt.y, pt.z, colRGBA); mesh_set_index(mesh, mesh->v_count-1); } mesh_update_bounds(mesh);}/*structures used for normal smoothing*/struct face_info{ /*face normal*/ SFVec3f nor; u32 idx_alloc; /*nb pts in face*/ u32 idx_count; /*indexes of face vertices in the pt_info structure*/ u32 *idx;};/*for each pt in the mesh*/struct pt_info{ u32 face_alloc; /*number of faces this point belongs to*/ u32 face_count; /*idx of face in face_info structure*/ u32 *faces;};void register_point_in_face(struct face_info *fi, u32 pt_index){ if (fi->idx_count==fi->idx_alloc) { fi->idx_alloc += 10; fi->idx = (u32*)realloc(fi->idx, sizeof(u32)*fi->idx_alloc); } fi->idx[fi->idx_count] = pt_index; fi->idx_count++;}void register_face_in_point(struct pt_info *pi, u32 face_index){ if (pi->face_count==pi->face_alloc) { pi->face_alloc += 10; pi->faces = (u32*)realloc(pi->faces, sizeof(u32)*pi->face_alloc); } pi->faces[pi->face_count] = face_index; pi->face_count++;}static GFINLINE SFVec3f smooth_face_normals(struct pt_info *pts, u32 nb_pts, struct face_info *faces, u32 nb_faces, u32 pt_idx_in_face, u32 face_idx, Fixed creaseAngleCos){ u32 i=0; SFVec3f nor; struct face_info *fi = &faces[face_idx]; struct pt_info *pi = &pts[fi->idx[pt_idx_in_face]]; nor = fi->nor; /*for each face adjacent this point/face*/ for (i=0; i<pi->face_count; i++) { /*current face, skip*/ if (pi->faces[i]==face_idx) continue; if (gf_vec_dot(fi->nor, faces[pi->faces[i]].nor) > creaseAngleCos) { gf_vec_add(nor, nor, faces[pi->faces[i]].nor); } } gf_vec_norm(&nor); return nor;}#define GET_IDX(idx, array) \ if (idx<array->count && (array->vals[idx]>=0) ) index = array->vals[idx]; \ else if (idx<c_count) index = idx; \ else index = 0; \void mesh_new_ifs_intern(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex, GF_Node *__color, MFInt32 *colorIndex, Bool colorPerVertex, GF_Node *__normal, MFInt32 *normalIndex, Bool normalPerVertex, GF_Node *__texCoords, MFInt32 *texCoordIndex, Fixed creaseAngle){ u32 i, n, count, c_count, col_count, nor_count; u32 index; u32 first_idx, last_idx; Bool move_to, smooth_normals; SFVec2f tx; u32 s_axis, t_axis; SFVec3f pt, nor, bounds, center; SFColorRGBA colRGBA; Bool has_color, has_coord, has_normal, has_tex, gen_tex_coords; GF_Mesh **faces; struct face_info *faces_info; struct pt_info *pts_info; u32 face_count, cur_face; M_Coordinate2D *coord2D = (M_Coordinate2D*) __coord; M_Coordinate *coord = (M_Coordinate*) __coord; M_Color *colorRGB = (M_Color *) __color; X_ColorRGBA *colorRGBA = (X_ColorRGBA *) __color; M_Normal *normal = (M_Normal*) __normal; M_TextureCoordinate *txcoord = (M_TextureCoordinate*) __texCoords; nor.x = nor.y = nor.z = 0; center = pt = bounds = nor; tx.x = tx.y = 0; if (__coord && (gf_node_get_tag(__coord) == TAG_MPEG4_Coordinate2D)) { coord = NULL; } else { coord2D = NULL; if (!__coord) return; /*not supported yet*/ if (gf_node_get_tag(__coord) == TAG_X3D_CoordinateDouble) return; } gen_tex_coords = 0; if (__texCoords && (gf_node_get_tag(__texCoords)==TAG_X3D_TextureCoordinateGenerator)) { gen_tex_coords = 1; txcoord = NULL; } if (!coord2D && !coord) return; c_count = coord2D ? coord2D->point.count : coord->point.count; if (!c_count) return; if (normal && normalIndex) { if (!normalIndex->vals) normalIndex = coordIndex; nor_count = normalIndex->count ? normalIndex->count : c_count; has_normal = normal->vector.count ? 1 : 0; } else { nor_count = 0; nor.x = nor.y = 0; nor.z = FIX_ONE; has_normal = 0; } has_tex = txcoord ? 1 : 0; if (has_tex && !texCoordIndex->vals) texCoordIndex = coordIndex; mesh_reset(mesh); memset(&colRGBA, 0, sizeof(SFColorRGBA)); /*compute bounds - note we assume all points in the IFS coordinate are used*/ s_axis = t_axis = 0; if (!has_tex) { for (i=0; i<c_count; i++) { if (coord2D) mesh_set_point(mesh, coord2D->point.vals[i].x, coord2D->point.vals[i].y, 0, colRGBA); else mesh_set_point(mesh, coord->point.vals[i].x, coord->point.vals[i].y, coord->point.vals[i].z, colRGBA); } mesh_update_bounds(mesh); gf_vec_diff(bounds, mesh->bounds.max_edge, mesh->bounds.min_edge); center = mesh->bounds.min_edge; if ( (bounds.x >= bounds.y) && (bounds.x >= bounds.z) ) { s_axis = 0; t_axis = (bounds.y >= bounds.z) ? 1 : 2; } else if ( (bounds.y >= bounds.x) && (bounds.y >= bounds.z) ) { s_axis = 1; t_axis = (bounds.x >= bounds.z) ? 0 : 2; } else { s_axis = 2; t_axis = (bounds.x >= bounds.y) ? 0 : 1; } } 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; } } n = 0; if (has_color) { if (!colorPerVertex) { index = colorIndex->count ? colorIndex->vals[0] : 0; MESH_GET_COL(colRGBA, index); } else { if (!colorIndex->vals) colorIndex = coordIndex; } } col_count = colorIndex->count ? colorIndex->count : c_count; if (has_normal && !normalPerVertex) { index = normalIndex->count ? normalIndex->vals[0] : 0; if (index < nor_count) nor = normal->vector.vals[index]; } move_to = 1; count = coordIndex->count; has_coord = count ? 1 : 0; if (!has_coord) count = c_count; smooth_normals = (!has_normal && coord && (creaseAngle > FIX_EPSILON)) ? 1 : 0; /*build face list*/ if (!has_coord) { face_count = 1; } else { u32 pt_p_face; face_count = 0; pt_p_face = 0; for (i=0; i<count; i++) { if (coordIndex->vals[i] == -1) face_count++; } /*don't forget last face*/ if (coordIndex->vals[count-1] != -1) face_count++; } faces = (GF_Mesh**)malloc(sizeof(GF_Mesh *)*face_count); for (i=0; i<face_count; i++) { faces[i] = new_mesh(); if (coord2D) faces[i]->flags = MESH_IS_2D; } faces_info = NULL; pts_info = NULL; /*alloc face & normals tables*/ if (smooth_normals) { faces_info = (struct face_info*)malloc(sizeof(struct face_info)*face_count); memset(faces_info, 0, sizeof(struct face_info)*face_count); pts_info = (struct pt_info*)malloc(sizeof(struct pt_info)*c_count); memset(pts_info, 0, sizeof(struct pt_info)*c_count); } cur_face = 0; first_idx = last_idx = 0; for (i=0; i<count; i++) { if (has_coord && coordIndex->vals[i] == -1) { move_to = 1; n++; if (has_color && !colorPerVertex) { GET_IDX(n, colorIndex); MESH_GET_COL(colRGBA, index); } if (has_normal && !normalPerVertex) { GET_IDX(n, normalIndex); if (index < nor_count) nor = normal->vector.vals[index]; } if (faces[cur_face]->v_count<3) faces[cur_face]->v_count=0; /*compute face normal - watchout for colinear vectors*/ else if (smooth_normals) { SFVec3f v1, v2, fn; u32 k=2; gf_vec_diff(v1, faces[cur_face]->vertices[1].pos, faces[cur_face]->vertices[0].pos); while (k<faces[cur_face]->v_count) { gf_vec_diff(v2, faces[cur_face]->vertices[k].pos, faces[cur_face]->vertices[0].pos); fn = gf_vec_cross(v1, v2); if (gf_vec_len(fn)) { gf_vec_norm(&fn); faces_info[cur_face].nor = fn; break; } k++; } } cur_face++; } else { if (has_color && colorPerVertex) { GET_IDX(i, colorIndex); MESH_GET_COL(colRGBA, index); } if (has_normal && normalPerVertex) { GET_IDX(i, normalIndex); if (index < normal->vector.count) { nor = normal->vector.vals[index]; } } if (has_coord) index = coordIndex->vals[i]; else index = i; if (index < c_count) { if (coord2D) { pt.x = coord2D->point.vals[index].x; pt.y = coord2D->point.vals[index].y; pt.z = 0; } else { pt = coord->point.vals[index]; } /*update face to point and point to face structures*/ if (smooth_normals) { register_point_in_face(&faces_info[cur_face], index); register_face_in_point(&pts_info[index], cur_face); } } if (has_tex) { GET_IDX(i, texCoordIndex); if (index < txcoord->point.count) tx = txcoord->point.vals[index]; } else { SFVec3f v; gf_vec_diff(v, pt, center); tx.x = tx.y = 0; if (s_axis==0) tx.x = gf_divfix(v.x, bounds.x); else if (s_axis==1) tx.x = gf_divfix(v.y, bounds.y); else if (s_axis==2) tx.x = gf_divfix(v.z, bounds.z); if (t_axis==0) tx.y = gf_divfix(v.x, bounds.x); else if (t_axis==1) tx.y = gf_divfix(v.y, bounds.y); else if (t_axis==2) tx.y = gf_divfix(v.z, bounds.z); } mesh_set_vertex_v(faces[cur_face], pt, nor, tx, colRGBA); } } /*generate normals*/ if (!has_normal && coord) { u32 j; 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, c_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<c_count; i++) if (pts_info[i].faces) free(pts_info[i].faces); free(pts_info); } mesh->flags |= MESH_IS_SMOOTHED; } else { for (i=0; i<face_count; i++) { SFVec3f v1, v2, n; gf_vec_diff(v1, faces[i]->vertices[1].pos, faces[i]->vertices[0].pos); gf_vec_diff(v2, faces[i]->vertices[2].pos, faces[i]->vertices[0].pos); n = gf_vec_cross(v1, v2); if (!n.x && !n.y && !n.z) n.z = FIX_ONE; else gf_vec_norm(&n); for (j=0; j<faces[i]->v_count; j++) faces[i]->vertices[j].normal = n; } } } mesh_reset(mesh); mesh->mesh_type = MESH_TRIANGLES; if (has_color) mesh->flags |= MESH_HAS_COLOR; for (i=0; i<face_count; i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -