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

📄 geometry_stacks.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	if (gf_node_dirty_get(node)) {		mesh_new_ifs(st->mesh, node);		gf_node_dirty_clear(node, 0);	}	if (!eff->traversing_mode) {		VS_DrawMesh(eff, st->mesh);	} else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}static void IFS_SetColorIndex(GF_Node *node){	M_IndexedFaceSet *ifs = (M_IndexedFaceSet *)node;	gf_sg_vrml_field_copy(&ifs->colorIndex, &ifs->set_colorIndex, GF_SG_VRML_MFINT32);	gf_sg_vrml_mf_reset(&ifs->set_colorIndex, GF_SG_VRML_MFINT32);}static void IFS_SetCoordIndex(GF_Node *node){	M_IndexedFaceSet *ifs = (M_IndexedFaceSet *)node;	gf_sg_vrml_field_copy(&ifs->coordIndex, &ifs->set_coordIndex, GF_SG_VRML_MFINT32);	gf_sg_vrml_mf_reset(&ifs->set_coordIndex, GF_SG_VRML_MFINT32);}static void IFS_SetNormalIndex(GF_Node *node){	M_IndexedFaceSet *ifs = (M_IndexedFaceSet *)node;	gf_sg_vrml_field_copy(&ifs->normalIndex, &ifs->set_normalIndex, GF_SG_VRML_MFINT32);	gf_sg_vrml_mf_reset(&ifs->set_normalIndex, GF_SG_VRML_MFINT32);}static void IFS_SetTexCoordIndex(GF_Node *node){	M_IndexedFaceSet *ifs = (M_IndexedFaceSet *)node;	gf_sg_vrml_field_copy(&ifs->texCoordIndex, &ifs->set_texCoordIndex, GF_SG_VRML_MFINT32);	gf_sg_vrml_mf_reset(&ifs->set_texCoordIndex, GF_SG_VRML_MFINT32);}void R3D_InitIFS(Render3D *sr, GF_Node *node){	M_IndexedFaceSet *ifs = (M_IndexedFaceSet *)node;	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderIFS);	ifs->on_set_colorIndex = IFS_SetColorIndex;	ifs->on_set_coordIndex = IFS_SetCoordIndex;	ifs->on_set_normalIndex = IFS_SetNormalIndex;	ifs->on_set_texCoordIndex = IFS_SetTexCoordIndex;}static void RenderILS(GF_Node *node, void *rs, Bool is_destroy){	M_IndexedLineSet *ils = (M_IndexedLineSet *)node;	DrawableStack *st = (DrawableStack *)gf_node_get_private(node);	RenderEffect3D *eff = (RenderEffect3D *)rs;	if (is_destroy) {		drawable_node_destroy(node);		return;	}	if (!ils->coord) return;	if (gf_node_dirty_get(node)) {		mesh_new_ils(st->mesh, ils->coord, &ils->coordIndex, ils->color, &ils->colorIndex, ils->colorPerVertex, 0);		gf_node_dirty_clear(node, 0);	}	if (!eff->traversing_mode) {		VS3D_SetAntiAlias(eff->surface, (eff->surface->render->compositor->antiAlias==GF_ANTIALIAS_FULL) ? 1 : 0);		VS_DrawMesh(eff, st->mesh);	} else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}static void ILS_SetColorIndex(GF_Node *node){	M_IndexedLineSet *ils = (M_IndexedLineSet *)node;	gf_sg_vrml_field_copy(&ils->colorIndex, &ils->set_colorIndex, GF_SG_VRML_MFINT32);	gf_sg_vrml_mf_reset(&ils->set_colorIndex, GF_SG_VRML_MFINT32);}static void ILS_SetCoordIndex(GF_Node *node){	M_IndexedLineSet *ils = (M_IndexedLineSet *)node;	gf_sg_vrml_field_copy(&ils->coordIndex, &ils->set_coordIndex, GF_SG_VRML_MFINT32);	gf_sg_vrml_mf_reset(&ils->set_coordIndex, GF_SG_VRML_MFINT32);}void R3D_InitILS(Render3D *sr, GF_Node *node){	M_IndexedLineSet *ils = (M_IndexedLineSet *)node;	DrawableStack *st = BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderILS);	ils->on_set_colorIndex = ILS_SetColorIndex;	ils->on_set_coordIndex = ILS_SetCoordIndex;	st->IntersectWithRay = R3D_NoIntersectionWithRay;}static void RenderElevationGrid(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)) {		mesh_new_elevation_grid(st->mesh, node);		gf_node_dirty_clear(node, 0);	}	if (!eff->traversing_mode) {		VS_DrawMesh(eff, st->mesh);	} else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}static void ElevationGrid_SetHeight(GF_Node *node){	M_ElevationGrid *eg = (M_ElevationGrid *)node;	gf_sg_vrml_field_copy(&eg->height, &eg->set_height, GF_SG_VRML_MFFLOAT);	gf_sg_vrml_mf_reset(&eg->set_height, GF_SG_VRML_MFFLOAT);}void R3D_InitElevationGrid(Render3D *sr, GF_Node *node){	M_ElevationGrid *eg = (M_ElevationGrid *)node;	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderElevationGrid);	eg->on_set_height = ElevationGrid_SetHeight;}static void RenderExtrusion(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)) {		mesh_new_extrusion(st->mesh, node);		gf_node_dirty_clear(node, 0);	}	if (!eff->traversing_mode) {		VS_DrawMesh(eff, st->mesh);	} else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}static void Extrusion_SetCrossSection(GF_Node *node){	M_Extrusion *eg = (M_Extrusion *)node;	gf_sg_vrml_field_copy(&eg->crossSection, &eg->set_crossSection, GF_SG_VRML_MFVEC2F);	gf_sg_vrml_mf_reset(&eg->set_crossSection, GF_SG_VRML_MFVEC2F);}static void Extrusion_SetOrientation(GF_Node *node){	M_Extrusion *eg = (M_Extrusion *)node;	gf_sg_vrml_field_copy(&eg->orientation, &eg->set_orientation, GF_SG_VRML_MFROTATION);	gf_sg_vrml_mf_reset(&eg->set_orientation, GF_SG_VRML_MFROTATION);}static void Extrusion_SetScale(GF_Node *node){	M_Extrusion *eg = (M_Extrusion *)node;	gf_sg_vrml_field_copy(&eg->scale, &eg->set_scale, GF_SG_VRML_MFVEC2F);	gf_sg_vrml_mf_reset(&eg->set_scale, GF_SG_VRML_MFVEC2F);}static void Extrusion_SetSpine(GF_Node *node){	M_Extrusion *eg = (M_Extrusion *)node;	gf_sg_vrml_field_copy(&eg->spine, &eg->set_spine, GF_SG_VRML_MFVEC3F);	gf_sg_vrml_mf_reset(&eg->set_spine, GF_SG_VRML_MFVEC3F);}void R3D_InitExtrusion(Render3D *sr, GF_Node *node){	M_Extrusion *ext = (M_Extrusion *)node;	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderExtrusion);	ext->on_set_crossSection = Extrusion_SetCrossSection;	ext->on_set_orientation = Extrusion_SetOrientation;	ext->on_set_scale = Extrusion_SetScale;	ext->on_set_spine = Extrusion_SetSpine;}/*			NonLinearDeformer	NOTE: AFX spec is just hmm, well, hmm. NonLinearDeformer.extend interpretation differ from type to 	type within the spec, and between the spec and the ref soft. This is GPAC interpretation	* all params are specified with default transform axis (Z axis)	* NLD.type = 0 (taper):		* taping radius = NLD.param		* extend = N * [diff, perc] with 			- diff : relative position along taper axis (for default, diff=0: z min, diff=1: z max)			- perc: mult ratio for base taper radius		extend works like key/keyValue for a scalar interpolator		final radius: r(z) = LinearInterp(extend[min key], extend[min key + 1]) * param	* NLD.type = 1 (twister):		* twisting angle = NLD.param		* extend = N * [diff, perc] with 			- diff : relative position along twister axis (for default, diff=0: z min, diff=1: z max)			- perc: mult ratio for base twister angle		extend works like key/keyValue for a scalar interpolator		final angle: a(z) = LinearInterp(extend[min key], extend[min key + 1]) * param	* NLD.type = 2 (bender):		* bending curvature = NLD.param		* extend = N * [diff, perc] with 			- diff : relative position along bender axis (for default, diff=0: z min, diff=1: z max)			- perc: mult ratio for base bender curvature		extend works like key/keyValue for a scalar interpolator		final curvature: c(z) = LinearInterp(extend[min key], extend[min key + 1]) * param  Another pb of NLD is that the spec says nothing about object/axis alignment: should we center  the object at 0,0,0 (local coords) or not? the results are quite different. Here we don't   recenter the object before transform*/static Bool NLD_GetMatrix(M_NonLinearDeformer *nld, GF_Matrix *mx){	SFVec3f v1, v2;	SFRotation r;	Fixed l1, l2, dot;	/*compute rotation matrix from NLD axis to 0 0 1*/	v1 = nld->axis;	gf_vec_norm(&v1);	v2.x = v2.y = 0; v2.z = FIX_ONE;	if (gf_vec_equal(v1, v2)) return 0;	l1 = gf_vec_len(v1);	l2 = gf_vec_len(v2);	dot = gf_divfix(gf_vec_dot(v1, v2), gf_mulfix(l1, l2));	r.x = gf_mulfix(v1.y, v2.z) - gf_mulfix(v2.y, v1.z);	r.y = gf_mulfix(v1.z, v2.x) - gf_mulfix(v2.z, v1.x);	r.z = gf_mulfix(v1.x, v2.y) - gf_mulfix(v2.x, v1.y);	r.q = gf_atan2(gf_sqrt(FIX_ONE - gf_mulfix(dot, dot)), dot);	gf_mx_init(*mx);	gf_mx_add_rotation(mx, r.q, r.x, r.y, r.z);	return 1;}static GFINLINE void NLD_GetKey(M_NonLinearDeformer *nld, Fixed frac, Fixed *f_min, Fixed *min, Fixed *f_max, Fixed *max){	u32 i, count;	count = nld->extend.count;	if (count%2) count--;	*f_min = 0;	*min = 0;	for (i=0; i<count; i+=2) {		if (frac>=nld->extend.vals[i]) {			*f_min = nld->extend.vals[i];			*min = nld->extend.vals[i+1];		} 		if ((i+2<count) && (frac<=nld->extend.vals[i+2])) {			*f_max = nld->extend.vals[i+2];			*max = nld->extend.vals[i+3];			return;		}	}	if (count) {		*f_max = nld->extend.vals[count-2];		*max = nld->extend.vals[count-1];	} else {		*f_max = FIX_ONE;		*max = GF_PI;	}}static void NLD_Apply(M_NonLinearDeformer *nld, GF_Mesh *mesh){	u32 i;	GF_Matrix mx;	Fixed param, z_min, z_max, v_min, v_max, f_min, f_max, frac, val, a_cos, a_sin;	Bool needs_transform = NLD_GetMatrix(nld, &mx);	param = nld->param;	if (!param) param = 1;		if (mesh->bounds.min_edge.z == mesh->bounds.max_edge.z) return;	z_min = FIX_MAX;	z_max = -FIX_MAX;	if (needs_transform) {		for (i=0; i<mesh->v_count; i++) {			gf_mx_apply_vec(&mx, &mesh->vertices[i].pos);			gf_mx_rotate_vector(&mx, &mesh->vertices[i].normal);			if (mesh->vertices[i].pos.z<z_min) z_min = mesh->vertices[i].pos.z;			if (mesh->vertices[i].pos.z>z_max) z_max = mesh->vertices[i].pos.z;		}	} else {		z_min = mesh->bounds.min_edge.z;		z_max = mesh->bounds.max_edge.z;	}		for (i=0; i<mesh->v_count; i++) {		SFVec3f old = mesh->vertices[i].pos;		frac = gf_divfix(old.z - z_min, z_max - z_min);		NLD_GetKey(nld, frac, &f_min, &v_min, &f_max, &v_max);		if (f_max == f_min) {			val = v_min;		} else {			frac = gf_divfix(frac-f_min, f_max - f_min);			val = gf_mulfix(v_max - v_min, frac) + v_min;		}		val = gf_mulfix(val, param);		switch (nld->type) {		/*taper*/		case 0:			mesh->vertices[i].pos.x = gf_mulfix(mesh->vertices[i].pos.x, val);			mesh->vertices[i].pos.y = gf_mulfix(mesh->vertices[i].pos.y, val);			old = mesh->vertices[i].normal;			mesh->vertices[i].normal.x = gf_mulfix(mesh->vertices[i].normal.x, val);			mesh->vertices[i].normal.y = gf_mulfix(mesh->vertices[i].normal.y, val);			gf_vec_norm(&mesh->vertices[i].normal);			break;		/*twist*/		case 1:			a_cos = gf_cos(val);			a_sin = gf_sin(val);			mesh->vertices[i].pos.x = gf_mulfix(a_cos, old.x) - gf_mulfix(a_sin, old.y);			mesh->vertices[i].pos.y = gf_mulfix(a_sin, old.x) + gf_mulfix(a_cos, old.y);			old = mesh->vertices[i].normal;			mesh->vertices[i].normal.x = gf_mulfix(a_cos, old.x) -  gf_mulfix(a_sin, old.y);			mesh->vertices[i].normal.y = gf_mulfix(a_sin, old.x) + gf_mulfix(a_cos, old.y);			gf_vec_norm(&mesh->vertices[i].normal);			break;		/*bend*/		case 2:			a_cos = gf_cos(val);			a_sin = gf_sin(val);			mesh->vertices[i].pos.x = gf_mulfix(a_sin, old.z) + gf_mulfix(a_cos, old.x);			mesh->vertices[i].pos.z = gf_mulfix(a_cos, old.z) - gf_mulfix(a_sin, old.x);			old = mesh->vertices[i].normal;			mesh->vertices[i].normal.x = gf_mulfix(a_sin, old.z) +  gf_mulfix(a_cos, old.x);			mesh->vertices[i].normal.z = gf_mulfix(a_cos, old.z) - gf_mulfix(a_sin, old.x);			gf_vec_norm(&mesh->vertices[i].normal);			break;		/*pinch, not standard  (taper on X dim only)*/		case 3:			mesh->vertices[i].pos.x = gf_mulfix(mesh->vertices[i].pos.x, val);			old = mesh->vertices[i].normal;			mesh->vertices[i].normal.x = gf_mulfix(mesh->vertices[i].normal.x, val);			gf_vec_norm(&mesh->vertices[i].normal);			break;		}	}	if (needs_transform) {		gf_mx_inverse(&mx);		for (i=0; i<mesh->v_count; i++) {			gf_mx_apply_vec(&mx, &mesh->vertices[i].pos);			gf_mx_rotate_vector(&mx, &mesh->vertices[i].normal);		}	}	mesh_update_bounds(mesh);	gf_mesh_build_aabbtree(mesh);}static void RenderNonLinearDeformer(GF_Node *n, void *rs, Bool is_destroy){	DrawableStack *st = (DrawableStack *) gf_node_get_private(n);	M_NonLinearDeformer *nld = (M_NonLinearDeformer*)n;	RenderEffect3D *eff = (RenderEffect3D *)rs;	if (is_destroy) {		drawable_node_destroy(n);		return;	}	if (!nld->geometry) return;	/*call render for get_bounds to make sure geometry is up to date*/	if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		gf_node_render(nld->geometry, eff);	}	/*invalidated*/	if (gf_node_dirty_get(n)) {		DrawableStack *geo_st = (DrawableStack *)gf_node_get_private(nld->geometry);		if (!geo_st) return;		gf_node_dirty_clear(n, 0);		mesh_clone(st->mesh, geo_st->mesh);		/*apply deforms*/		NLD_Apply(nld, st->mesh);	}	if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}	/*in case there's a cascading of NLDs*/	else if (!eff->traversing_mode && eff->appear) {		VS_DrawMesh(eff, st->mesh);	}}void R3D_InitNonLinearDeformer(Render3D *sr, GF_Node *node){	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderNonLinearDeformer);}

⌨️ 快捷键说明

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