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

📄 geometry_x3d.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
{	u32 strip, i, cur_idx, generate_tx;	GF_Vertex vx;	GenMFField *cols;	MFVec3f *norms;	MFVec2f *txcoords;	Bool rgba_col;	X_Coordinate *c = (X_Coordinate *) _coords;		mesh_reset(mesh);		cols = NULL;	rgba_col = 0;	if (_color) {		if (gf_node_get_tag(_color)==TAG_X3D_ColorRGBA) {			rgba_col = 1;			cols = (GenMFField *) & ((X_ColorRGBA *) _color)->color;		} else {			cols = (GenMFField *) & ((M_Color *) _color)->color;		}	}	norms = NULL;	if (_normal) norms = & ((M_Normal *)_normal)->vector;	txcoords = NULL;	generate_tx = 0;	/*FIXME - this can't work with multitexturing*/	if (_txcoords) {		switch (gf_node_get_tag(_txcoords)) {		case TAG_X3D_TextureCoordinate:		case TAG_MPEG4_TextureCoordinate:			txcoords = & ((M_TextureCoordinate *)_txcoords)->point;			break;		case TAG_X3D_TextureCoordinateGenerator:			generate_tx = 1;			break;		}	}	memset(&vx, 0, sizeof(GF_Vertex));	cur_idx = 0;	for (strip= 0; strip<stripList->count; strip++) {		u32 start_idx = mesh->v_count;		if (stripList->vals[strip] < 3) continue;		for (i=0; i<(u32) stripList->vals[strip]; i++) {			u32 idx;			if (indices) {				if (indices->count<=cur_idx) return;				if (indices->vals[cur_idx] == -1) {					GF_LOG(GF_LOG_ERROR, GF_LOG_RENDER, ("[Render 3D] bad formatted X3D triangle strip\n"));					return;				}				idx = indices->vals[cur_idx];			} else {				idx = cur_idx;			}			vx.pos = c->point.vals[idx];			if (cols && (cols->count>idx)) {				if (rgba_col) {					vx.color = ((MFColorRGBA *)cols)->vals[idx];				} else {					vx.color = gf_sg_sfcolor_to_rgba( ((MFColor *)cols)->vals[idx]);				}			}			/*according to X3D spec, if normal field is set, it is ALWAYS as normal per vertex*/			if (norms && (norms->count>idx)) {				vx.normal = norms->vals[idx];				gf_vec_norm(&vx.normal);			}			if (txcoords) {				if (txcoords->count>idx) vx.texcoords = txcoords->vals[idx];			} 			/*X3D says nothing about default texture mapping here...*/			else if (!generate_tx) {				switch (idx%3) {				case 2: vx.texcoords.x = FIX_ONE; vx.texcoords.y = 0; break;				case 1: vx.texcoords.x = FIX_ONE/2; vx.texcoords.y = FIX_ONE; break;				case 0: vx.texcoords.x = 0; vx.texcoords.y = 0; break;				}			}			if (i>2) {				/*duplicate last 2 vertices (we really need independent vertices to handle normals per face)*/				mesh_set_vertex_vx(mesh, &mesh->vertices[mesh->v_count-2]);				mesh_set_vertex_vx(mesh, &mesh->vertices[mesh->v_count-2]);			}			mesh_set_vertex_vx(mesh, &vx);			cur_idx ++;			if (indices) {				if (cur_idx>=indices->count) break;			} else if (cur_idx==c->point.count) break;		}		for (i=start_idx; i<mesh->v_count; i+=3) {			mesh_set_triangle(mesh, i, i+1, i+2);		}		/*get rid of -1*/		if (indices && (cur_idx<indices->count) && (indices->vals[cur_idx]==-1)) cur_idx++;	}	if (generate_tx) mesh_generate_tex_coords(mesh, _txcoords);	if (cols) mesh->flags |= MESH_HAS_COLOR;	if (rgba_col) mesh->flags |= MESH_HAS_ALPHA;	if (_normal) {		if (!ccw) mesh->flags |= MESH_IS_CW;	}	/*reorder everything to CCW*/	else {		u32 cur_face = 0;		mesh_recompute_normals(mesh);		for (i=0; i<mesh->i_count; i+= 3) {			if ((ccw && (cur_face%2)) || (!ccw && !(cur_face%2))) {				SFVec3f v;				u32 idx;				v = gf_vec_scale(mesh->vertices[mesh->indices[i]].normal,-1);				mesh->vertices[mesh->indices[i]].normal = v;				mesh->vertices[mesh->indices[i+1]].normal = v;				mesh->vertices[mesh->indices[i+2]].normal = v;				idx = mesh->indices[i+2];				mesh->indices[i+2] = mesh->indices[i+1];				mesh->indices[i+1] = idx;			}			cur_face++;		}		if (normalPerVertex) {			cur_face = 0;			for (strip=0; strip<stripList->count; strip++) {				SFVec3f n_0, n_1, n_2, n_avg;				u32 nb_face;				if (stripList->vals[strip] < 3) continue;				if (stripList->vals[strip] <= 3) { cur_face ++; continue; }				/*first face normal*/				n_0 = mesh->vertices[mesh->indices[3*cur_face]].normal;				/*second face normal*/				n_1 = mesh->vertices[mesh->indices[3*(cur_face+1)]].normal;				gf_vec_add(n_avg, n_0, n_1);				gf_vec_norm(&n_avg);				/*assign to second point of first face and first of second face*/				mesh->vertices[mesh->indices[3*cur_face+1]].normal = n_avg;				mesh->vertices[mesh->indices[3*(cur_face+1)]].normal = n_avg;				nb_face = stripList->vals[strip] - 2;				cur_face++;				for (i=1; i<nb_face-1; i++) {					/*get normal (use second pt of current face since first has been updated)*/					n_2 = mesh->vertices[mesh->indices[3*cur_face + 1]].normal;					gf_vec_add(n_avg, n_0, n_1);					gf_vec_add(n_avg, n_avg, n_2);					gf_vec_norm(&n_avg);					/*last of prev face*/					mesh->vertices[mesh->indices[3*cur_face - 1]].normal = n_avg;					/*second of current face*/					mesh->vertices[mesh->indices[3*cur_face + 1]].normal = n_avg;					/*first of next face*/					mesh->vertices[mesh->indices[3*cur_face + 3]].normal = n_avg;					n_0 = n_1;					n_1 = n_2;					cur_face++;				}			}		}	}	if (solid) mesh->flags |= MESH_IS_SOLID;	mesh_update_bounds(mesh);	gf_mesh_build_aabbtree(mesh);}static void RenderTriangleStripSet(GF_Node *node, void *rs, Bool is_destroy){	X_TriangleStripSet *tss = (X_TriangleStripSet *)node;	DrawableStack *st = (DrawableStack *)gf_node_get_private(node);	RenderEffect3D *eff = (RenderEffect3D *)rs;	if (is_destroy) {		drawable_node_destroy(node);		return;	}	if (!tss->coord) return;	if (gf_node_dirty_get(node)) {		gf_node_dirty_clear(node, 0);		BuildTriangleStripSet(st->mesh, tss->coord, tss->color, tss->texCoord, tss->normal, &tss->stripCount, NULL, tss->normalPerVertex, tss->ccw, tss->solid);	}	if (!eff->traversing_mode) {		VS_DrawMesh(eff, st->mesh);	} else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}void R3D_InitTriangleStripSet(Render3D *sr, GF_Node *node){	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderTriangleStripSet);}static void RenderIndexedTriangleStripSet(GF_Node *node, void *rs, Bool is_destroy){	DrawableStack *st = (DrawableStack *)gf_node_get_private(node);	RenderEffect3D *eff = (RenderEffect3D *)rs;	if (is_destroy) {		drawable_node_destroy(node);		return;	}	if (gf_node_dirty_get(node)) {		MFInt32 stripList;		u32 i, nb_strips;		X_IndexedTriangleStripSet *itss = (X_IndexedTriangleStripSet *)node;		gf_node_dirty_clear(node, 0);		if (!itss->coord) return;		stripList.count = 0; stripList.vals = NULL;		nb_strips = 0;		for (i=0; i<itss->index.count; i++) {			if (itss->index.vals[i]==-1) {				if (nb_strips>=3) {					u32 *out_nb;					gf_sg_vrml_mf_append(&stripList, GF_SG_VRML_MFINT32, (void **) &out_nb);					*out_nb = nb_strips;				}				nb_strips = 0;			} else {				nb_strips++;			}		}		if (nb_strips>=3) {			u32 *out_nb;			gf_sg_vrml_mf_append(&stripList, GF_SG_VRML_MFINT32, (void **) &out_nb);			*out_nb = nb_strips;		}		BuildTriangleStripSet(st->mesh, itss->coord, itss->color, itss->texCoord, itss->normal, &stripList, &itss->index, itss->normalPerVertex, itss->ccw, itss->solid);		gf_sg_vrml_mf_reset(&stripList, GF_SG_VRML_MFINT32);	}	if (!eff->traversing_mode) {		VS_DrawMesh(eff, st->mesh);	} else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}static void ITSS_SetIndex(GF_Node *node){	X_IndexedTriangleStripSet *itss = (X_IndexedTriangleStripSet*)node;	gf_sg_vrml_field_copy(&itss->index, &itss->set_index, GF_SG_VRML_MFINT32);	gf_sg_vrml_mf_reset(&itss->set_index, GF_SG_VRML_MFINT32);}void R3D_InitIndexedTriangleStripSet(Render3D *sr, GF_Node *node){	X_IndexedTriangleStripSet *itss = (X_IndexedTriangleStripSet*)node;	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderIndexedTriangleStripSet);	itss->on_set_index = ITSS_SetIndex;}static void BuildTriangleFanSet(GF_Mesh *mesh, GF_Node *_coords, GF_Node *_color, GF_Node *_txcoords, GF_Node *_normal, MFInt32 *fanList, MFInt32 *indices, Bool normalPerVertex, Bool ccw, Bool solid){	u32 fan, i, cur_idx, generate_tx;	GF_Vertex vx;	GenMFField *cols;	MFVec3f *norms;	MFVec2f *txcoords;	Bool rgba_col;	X_Coordinate *c = (X_Coordinate *) _coords;	mesh_reset(mesh);			cols = NULL;	rgba_col = 0;	if (_color) {		if (gf_node_get_tag(_color)==TAG_X3D_ColorRGBA) {			rgba_col = 1;			cols = (GenMFField *) & ((X_ColorRGBA *) _color)->color;		} else {			cols = (GenMFField *) & ((M_Color *) _color)->color;		}	}	norms = NULL;	if (_normal) norms = & ((M_Normal *)_normal)->vector;	txcoords = NULL;	generate_tx = 0;	/*FIXME - this can't work with multitexturing*/	if (_txcoords) {		switch (gf_node_get_tag(_txcoords)) {		case TAG_X3D_TextureCoordinate:		case TAG_MPEG4_TextureCoordinate:			txcoords = & ((M_TextureCoordinate *)_txcoords)->point;			break;		case TAG_X3D_TextureCoordinateGenerator:			generate_tx = 1;			break;		}	}	memset(&vx, 0, sizeof(GF_Vertex));	cur_idx = 0;	for (fan= 0; fan<fanList->count; fan++) {		u32 start_idx = mesh->v_count;		if (fanList->vals[fan] < 3) continue;		for (i=0; i<(u32) fanList->vals[fan]; i++) {			u32 idx;			if (indices) {				if (indices->count<=cur_idx) return;				if (indices->vals[cur_idx] == -1) {					GF_LOG(GF_LOG_ERROR, GF_LOG_RENDER, ("[Render 3D] bad formatted X3D triangle set\n"));					return;				}				idx = indices->vals[cur_idx];			} else {				idx = cur_idx;			}			vx.pos = c->point.vals[idx];			if (cols && (cols->count>idx)) {				if (rgba_col) {					vx.color = ((MFColorRGBA *)cols)->vals[idx];				} else {					vx.color = gf_sg_sfcolor_to_rgba( ((MFColor *)cols)->vals[idx]);				}			}			/*according to X3D spec, if normal field is set, it is ALWAYS as normal per vertex*/			if (norms && (norms->count>idx)) {				vx.normal = norms->vals[idx];				gf_vec_norm(&vx.normal);			}			if (txcoords) {				if (txcoords->count>idx) vx.texcoords = txcoords->vals[idx];			} 			/*X3D says nothing about default texture mapping here...*/			else if (!generate_tx) {				switch (idx%3) {				case 2: vx.texcoords.x = FIX_ONE; vx.texcoords.y = 0; break;				case 1: vx.texcoords.x = FIX_ONE/2; vx.texcoords.y = FIX_ONE; break;				case 0: vx.texcoords.x = 0; vx.texcoords.y = 0; break;				}			}			mesh_set_vertex_vx(mesh, &vx);			cur_idx ++;			if (indices) {				if (cur_idx>=indices->count) break;			} else if (cur_idx==c->point.count) break;						if (i>1) {				mesh_set_vertex_vx(mesh, &mesh->vertices[start_idx]);				mesh_set_vertex_vx(mesh, &vx);			}		}		for (i=start_idx; i<mesh->v_count; i+=3) {			mesh_set_triangle(mesh, i, i+1, i+2);		}		/*get rid of -1*/		if (indices && (cur_idx<indices->count) && (indices->vals[cur_idx]==-1)) cur_idx++;	}	if (generate_tx) mesh_generate_tex_coords(mesh, _txcoords);	if (cols) mesh->flags |= MESH_HAS_COLOR;	if (rgba_col) mesh->flags |= MESH_HAS_ALPHA;	if (!ccw) mesh->flags |= MESH_IS_CW;	if (!_normal) {		mesh_recompute_normals(mesh);		if (normalPerVertex) {			u32 cur_face = 0;			for (fan=0; fan<fanList->count; fan++) {				SFVec3f n_0, n_1, n_avg, n_tot;				u32 nb_face, start_face;				if (fanList->vals[fan] < 3) continue;				if (fanList->vals[fan] == 3) { cur_face++; continue; }					start_face = cur_face;				/*first face normal*/				n_0 = mesh->vertices[mesh->indices[3*cur_face]].normal;				n_tot = n_0;				cur_face++;				nb_face = fanList->vals[fan] - 2;				for (i=1; i<nb_face; i++) {					n_1 = mesh->vertices[mesh->indices[3*cur_face + 1]].normal;					gf_vec_add(n_avg, n_0, n_1);					gf_vec_norm(&n_avg);					mesh->vertices[mesh->indices[3*cur_face + 1]].normal = n_avg;					gf_vec_add(n_tot, n_tot, n_1);					n_0 = n_1;					cur_face++;				}				/*and assign center normal*/				gf_vec_norm(&n_tot);				for (i=0; i<nb_face; i++) {					mesh->vertices[mesh->indices[3*(i+start_face)]].normal = n_tot;				}			}		}	}	if (solid) mesh->flags |= MESH_IS_SOLID;	mesh_update_bounds(mesh);	gf_mesh_build_aabbtree(mesh);}static void RenderTriangleFanSet(GF_Node *node, void *rs, Bool is_destroy){	DrawableStack *st = (DrawableStack *)gf_node_get_private(node);	RenderEffect3D *eff = (RenderEffect3D *)rs;	if (is_destroy) {		drawable_node_destroy(node);		return;	}	if (gf_node_dirty_get(node)) {		X_TriangleFanSet *tfs = (X_TriangleFanSet *)node;		gf_node_dirty_clear(node, 0);		if (!tfs->coord) return;		BuildTriangleFanSet(st->mesh, tfs->coord, tfs->color, tfs->texCoord, tfs->normal, &tfs->fanCount, NULL, tfs->normalPerVertex, tfs->ccw, tfs->solid);	}	if (!eff->traversing_mode) {		VS_DrawMesh(eff, st->mesh);	} else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}void R3D_InitTriangleFanSet(Render3D *sr, GF_Node *node){	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderTriangleFanSet);}static void RenderIndexedTriangleFanSet(GF_Node *node, void *rs, Bool is_destroy){	DrawableStack *st = (DrawableStack *)gf_node_get_private(node);	RenderEffect3D *eff = (RenderEffect3D *)rs;	if (is_destroy) {		drawable_node_destroy(node);		return;	}	if (gf_node_dirty_get(node)) {		MFInt32 fanList;		u32 i, nb_fans;		X_IndexedTriangleFanSet *itfs = (X_IndexedTriangleFanSet *)node;		gf_node_dirty_clear(node, 0);		if (!itfs->coord) return;		fanList.count = 0; fanList.vals = NULL;		nb_fans = 0;		for (i=0; i<itfs->index.count; i++) {			if (itfs->index.vals[i]==-1) {				if (nb_fans>=3) {					u32 *out_nb;					gf_sg_vrml_mf_append(&fanList, GF_SG_VRML_MFINT32, (void **) &out_nb);					*out_nb = nb_fans;				}				nb_fans = 0;			} else {				nb_fans++;			}		}		if (nb_fans>=3) {			u32 *out_nb;			gf_sg_vrml_mf_append(&fanList, GF_SG_VRML_MFINT32, (void **) &out_nb);			*out_nb = nb_fans;		}		BuildTriangleFanSet(st->mesh, itfs->coord, itfs->color, itfs->texCoord, itfs->normal, &fanList, &itfs->index, itfs->normalPerVertex, itfs->ccw, itfs->solid);		gf_sg_vrml_mf_reset(&fanList, GF_SG_VRML_MFINT32);	}	if (!eff->traversing_mode) {		VS_DrawMesh(eff, st->mesh);	} else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}static void ITFS_SetIndex(GF_Node *node){	X_IndexedTriangleFanSet *itfs = (X_IndexedTriangleFanSet *)node;	gf_sg_vrml_field_copy(&itfs->index, &itfs->set_index, GF_SG_VRML_MFINT32);	gf_sg_vrml_mf_reset(&itfs->set_index, GF_SG_VRML_MFINT32);}void R3D_InitIndexedTriangleFanSet(Render3D *sr, GF_Node *node){	X_IndexedTriangleFanSet *itfs = (X_IndexedTriangleFanSet *)node;	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderIndexedTriangleFanSet);	itfs->on_set_index = ITFS_SetIndex;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -