⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mesh.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -