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

📄 hardcoded_protos.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / 3D rendering module * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include "render3d_nodes.h"#include "grouping.h"/*PathExtrusion hardcoded proto*/typedef struct{    GF_Node *geometry;    MFVec3f *spine;    Bool beginCap;    Bool endCap;    Fixed creaseAngle;    MFRotation *orientation;    MFVec2f *scale;    Bool txAlongSpine;} PathExtrusion;static Bool PathExtrusion_GetNode(GF_Node *node, PathExtrusion *path_ext){	GF_FieldInfo field;	memset(path_ext, 0, sizeof(PathExtrusion));	if (gf_node_get_field(node, 0, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_SFNODE) return 0;	path_ext->geometry = * (GF_Node **) field.far_ptr;	if (gf_node_get_field(node, 1, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_MFVEC3F) return 0;	path_ext->spine = (MFVec3f *) field.far_ptr;	if (gf_node_get_field(node, 2, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_SFBOOL) return 0;	path_ext->beginCap = *(SFBool *) field.far_ptr;	if (gf_node_get_field(node, 3, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_SFBOOL) return 0;	path_ext->endCap = *(SFBool *) field.far_ptr;	if (gf_node_get_field(node, 4, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_SFFLOAT) return 0;	path_ext->creaseAngle = *(SFFloat *) field.far_ptr;	if (gf_node_get_field(node, 5, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_MFROTATION) return 0;	path_ext->orientation = (MFRotation *) field.far_ptr;	if (gf_node_get_field(node, 6, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_MFVEC2F) return 0;	path_ext->scale = (MFVec2f *) field.far_ptr;	if (gf_node_get_field(node, 7, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_SFBOOL) return 0;	path_ext->txAlongSpine = *(SFBool *) field.far_ptr;	return 1;}static void RenderPathExtrusion(GF_Node *node, void *rs, Bool is_destroy){	PathExtrusion path_ext;	stack2D *st2D;	RenderEffect3D *eff = (RenderEffect3D *)rs;	DrawableStack *st = (DrawableStack *)gf_node_get_private(node);		if (is_destroy) {		drawable_node_destroy(node);		return;	}	if (!PathExtrusion_GetNode(node, &path_ext)) return;	if (!path_ext.geometry) return;	if (gf_node_dirty_get(node)) {		gf_node_render(path_ext.geometry, eff);		gf_node_dirty_clear(node, 0);		switch (gf_node_get_tag(path_ext.geometry) ) {		case TAG_MPEG4_Circle:		case TAG_MPEG4_Ellipse:		case TAG_MPEG4_Rectangle:		case TAG_MPEG4_Curve2D:		case TAG_MPEG4_XCurve2D:		case TAG_MPEG4_IndexedFaceSet2D:		case TAG_MPEG4_IndexedLineSet2D:			st2D = (stack2D*)gf_node_get_private(path_ext.geometry);			if (!st2D) return;			mesh_extrude_path(st->mesh, st2D->path, path_ext.spine, path_ext.creaseAngle, path_ext.beginCap, path_ext.endCap, path_ext.orientation, path_ext.scale, path_ext.txAlongSpine);			break;		case TAG_MPEG4_Text:			Text_Extrude(path_ext.geometry, eff, st->mesh, path_ext.spine, path_ext.creaseAngle, path_ext.beginCap, path_ext.endCap, path_ext.orientation, path_ext.scale, path_ext.txAlongSpine);			break;		}	}	if (!eff->traversing_mode) {		VS_DrawMesh(eff, st->mesh);	} else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}void R3D_InitPathExtrusion(Render3D *sr, GF_Node *node){	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderPathExtrusion);}/*PlanarExtrusion hardcoded proto*/typedef struct{    GF_Node *geometry;    GF_Node *spine;    Bool beginCap;    Bool endCap;    Fixed creaseAngle;	MFFloat *orientationKeys;    MFRotation *orientation;	MFFloat *scaleKeys;    MFVec2f *scale;    Bool txAlongSpine;} PlanarExtrusion;static Bool PlanarExtrusion_GetNode(GF_Node *node, PlanarExtrusion *path_ext){	GF_FieldInfo field;	memset(path_ext, 0, sizeof(PathExtrusion));	if (gf_node_get_field(node, 0, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_SFNODE) return 0;	path_ext->geometry = * (GF_Node **) field.far_ptr;	if (gf_node_get_field(node, 1, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_SFNODE) return 0;	path_ext->spine = * (GF_Node **) field.far_ptr;	if (gf_node_get_field(node, 2, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_SFBOOL) return 0;	path_ext->beginCap = *(SFBool *) field.far_ptr;	if (gf_node_get_field(node, 3, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_SFBOOL) return 0;	path_ext->endCap = *(SFBool *) field.far_ptr;	if (gf_node_get_field(node, 4, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_SFFLOAT) return 0;	path_ext->creaseAngle = *(SFFloat *) field.far_ptr;	if (gf_node_get_field(node, 5, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_MFFLOAT) return 0;	path_ext->orientationKeys = (MFFloat *) field.far_ptr;	if (gf_node_get_field(node, 6, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_MFROTATION) return 0;	path_ext->orientation = (MFRotation *) field.far_ptr;	if (gf_node_get_field(node, 7, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_MFFLOAT) return 0;	path_ext->scaleKeys = (MFFloat *) field.far_ptr;	if (gf_node_get_field(node, 8, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_MFVEC2F) return 0;	path_ext->scale = (MFVec2f *) field.far_ptr;	if (gf_node_get_field(node, 9, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_SFBOOL) return 0;	path_ext->txAlongSpine = *(SFBool *) field.far_ptr;	return 1;}static void RenderPlanarExtrusion(GF_Node *node, void *rs, Bool is_destroy){	PlanarExtrusion plane_ext;	stack2D *st2D;	u32 i, j, k;	MFVec3f spine_vec;	SFVec3f d;	Fixed spine_len;	GF_Rect bounds;	GF_Path *geo, *spine;	RenderEffect3D *eff = (RenderEffect3D *)rs;	DrawableStack *st = (DrawableStack *)gf_node_get_private(node);	if (is_destroy) {		drawable_node_destroy(node);		return;	}	if (!PlanarExtrusion_GetNode(node, &plane_ext)) return;	if (!plane_ext.geometry || !plane_ext.spine) return;	if (gf_node_dirty_get(node)) {		u32 cur, nb_pts;		geo = spine = NULL;		gf_node_render(plane_ext.geometry, eff);		gf_node_render(plane_ext.spine, eff);		gf_node_dirty_clear(node, 0);		switch (gf_node_get_tag(plane_ext.geometry) ) {		case TAG_MPEG4_Circle:		case TAG_MPEG4_Ellipse:		case TAG_MPEG4_Rectangle:		case TAG_MPEG4_Curve2D:		case TAG_MPEG4_XCurve2D:		case TAG_MPEG4_IndexedFaceSet2D:		case TAG_MPEG4_IndexedLineSet2D:			st2D = (stack2D*)gf_node_get_private(plane_ext.geometry);			if (st2D) geo = st2D->path;			break;		default:			return;		}		switch (gf_node_get_tag(plane_ext.spine) ) {		case TAG_MPEG4_Circle:		case TAG_MPEG4_Ellipse:		case TAG_MPEG4_Rectangle:		case TAG_MPEG4_Curve2D:		case TAG_MPEG4_XCurve2D:		case TAG_MPEG4_IndexedFaceSet2D:		case TAG_MPEG4_IndexedLineSet2D:			st2D = (stack2D*)gf_node_get_private(plane_ext.spine);			if (st2D) spine = st2D->path;			break;		default:			return;		}		if (!geo || !spine) return;		mesh_reset(st->mesh);		gf_path_flatten(spine);		gf_path_get_bounds(spine, &bounds);		gf_path_flatten(geo);		gf_path_get_bounds(geo, &bounds);		cur = 0;		for (i=0; i<spine->n_contours; i++) {			nb_pts = 1 + spine->contours[i] - cur;			spine_vec.vals = NULL;			gf_sg_vrml_mf_alloc(&spine_vec, GF_SG_VRML_MFVEC3F, nb_pts); 			spine_len = 0;			for (j=cur; j<nb_pts; j++) {				spine_vec.vals[j].x = spine->points[j].x;				spine_vec.vals[j].y = spine->points[j].y;				spine_vec.vals[j].z = 0;				if (j) {					gf_vec_diff(d, spine_vec.vals[j], spine_vec.vals[j-1]);					spine_len += gf_vec_len(d);				}			}			cur += nb_pts;			if (!plane_ext.orientation->count && !plane_ext.scale->count) {				mesh_extrude_path_ext(st->mesh, geo, &spine_vec, plane_ext.creaseAngle, 					bounds.x, bounds.y-bounds.height, bounds.width, bounds.height, 					plane_ext.beginCap, plane_ext.endCap, NULL, NULL, plane_ext.txAlongSpine);			}			/*interpolate orientation and scale along subpath line*/			else {				MFRotation ori;				MFVec2f scale;				Fixed cur_len, frac;				ori.vals = NULL;				gf_sg_vrml_mf_alloc(&ori, GF_SG_VRML_MFROTATION, nb_pts);				scale.vals = NULL;				gf_sg_vrml_mf_alloc(&scale, GF_SG_VRML_MFVEC2F, nb_pts);				cur_len = 0;				if (!plane_ext.orientation->count) ori.vals[0].y = FIX_ONE;				if (!plane_ext.scale->count) scale.vals[0].x = scale.vals[0].y = FIX_ONE;				for (j=0; j<nb_pts; j++) {					if (j) {						gf_vec_diff(d, spine_vec.vals[j], spine_vec.vals[j-1]);						cur_len += gf_vec_len(d);						ori.vals[j] = ori.vals[j-1];						scale.vals[j] = scale.vals[j-1];					}					if (plane_ext.orientation->count && (plane_ext.orientation->count == plane_ext.orientationKeys->count)) {						frac = gf_divfix(cur_len , spine_len);						if (frac < plane_ext.orientationKeys->vals[0]) ori.vals[j] = plane_ext.orientation->vals[0];						else if (frac >= plane_ext.orientationKeys->vals[plane_ext.orientationKeys->count-1]) ori.vals[j] = plane_ext.orientation->vals[plane_ext.orientationKeys->count-1];						else {							for (k=1; k<plane_ext.orientationKeys->count; k++) {								Fixed kDiff = plane_ext.orientationKeys->vals[k] - plane_ext.orientationKeys->vals[k-1];								if (!kDiff) continue;								if (frac < plane_ext.orientationKeys->vals[k-1]) continue; 								if (frac > plane_ext.orientationKeys->vals[k]) continue; 								frac = gf_divfix(frac - plane_ext.orientationKeys->vals[k-1], kDiff);								break;							}							ori.vals[j] = gf_sg_sfrotation_interpolate(plane_ext.orientation->vals[k-1], plane_ext.orientation->vals[k], frac);						}					}					if (plane_ext.scale->count == plane_ext.scaleKeys->count) {						frac = gf_divfix(cur_len , spine_len);						if (frac <= plane_ext.scaleKeys->vals[0]) scale.vals[j] = plane_ext.scale->vals[0];						else if (frac >= plane_ext.scaleKeys->vals[plane_ext.scaleKeys->count-1]) scale.vals[j] = plane_ext.scale->vals[plane_ext.scale->count-1];						else {							for (k=1; k<plane_ext.scaleKeys->count; k++) {								Fixed kDiff = plane_ext.scaleKeys->vals[k] - plane_ext.scaleKeys->vals[k-1];								if (!kDiff) continue;								if (frac < plane_ext.scaleKeys->vals[k-1]) continue; 								if (frac > plane_ext.scaleKeys->vals[k]) continue; 								frac = gf_divfix(frac - plane_ext.scaleKeys->vals[k-1], kDiff);								break;							}							scale.vals[j].x = gf_mulfix(plane_ext.scale->vals[k].x - plane_ext.scale->vals[k-1].x, frac) + plane_ext.scale->vals[k-1].x;							scale.vals[j].y = gf_mulfix(plane_ext.scale->vals[k].y - plane_ext.scale->vals[k-1].y, frac) + plane_ext.scale->vals[k-1].y;						}					}				}				mesh_extrude_path_ext(st->mesh, geo, &spine_vec, plane_ext.creaseAngle, 					bounds.x, bounds.y-bounds.height, bounds.width, bounds.height, 					plane_ext.beginCap, plane_ext.endCap, &ori, &scale, plane_ext.txAlongSpine);				gf_sg_vrml_mf_reset(&ori, GF_SG_VRML_MFROTATION);				gf_sg_vrml_mf_reset(&scale, GF_SG_VRML_MFVEC2F);			}			gf_sg_vrml_mf_reset(&spine_vec, GF_SG_VRML_MFVEC3F);		}		mesh_update_bounds(st->mesh);		gf_mesh_build_aabbtree(st->mesh);	}	if (!eff->traversing_mode) {		VS_DrawMesh(eff, st->mesh);	} else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}void R3D_InitPlanarExtrusion(Render3D *sr, GF_Node *node){	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderPlanarExtrusion);}/*PlaneClipper hardcoded proto*/typedef struct{    SFVec3f normal;    Fixed dist;	GF_ChildNodeItem *children;} PlaneClipper;static Bool PlaneClipper_GetNode(GF_Node *node, PlaneClipper *pc){	GF_FieldInfo field;	memset(pc, 0, sizeof(PlaneClipper));	if (gf_node_get_field(node, 0, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_SFVEC3F) return 0;	pc->normal = * (SFVec3f *) field.far_ptr;	if (gf_node_get_field(node, 1, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_SFFLOAT) return 0;	pc->dist = * (SFFloat *) field.far_ptr;	if (gf_node_get_field(node, 2, &field) != GF_OK) return 0;	if (field.fieldType != GF_SG_VRML_MFNODE) return 0;	pc->children = *(GF_ChildNodeItem **) field.far_ptr;	return 1;}static void RenderPlaneClipper(GF_Node *node, void *rs, Bool is_destroy){	PlaneClipper pc;	GF_Plane p;	GroupingNode *st = (GroupingNode *)gf_node_get_private(node);	RenderEffect3D *eff = (RenderEffect3D *) rs;	if (is_destroy) {		DeleteGroupingNode(st);		return;	}	if (!PlaneClipper_GetNode(node, &pc)) return;	if (eff->num_clip_planes==MAX_USER_CLIP_PLANES) {		grouping_traverse(st, eff, NULL);		return;	}	p.normal = pc.normal;	p.d = pc.dist;	eff->clip_planes[eff->num_clip_planes] = p;	gf_mx_apply_plane(&eff->model_matrix, &eff->clip_planes[eff->num_clip_planes]);	eff->num_clip_planes++;	if (eff->traversing_mode == TRAVERSE_SORT) {		GF_Plane p;		p.normal = pc.normal;		p.d = pc.dist;		VS3D_SetClipPlane(eff->surface, p);		grouping_traverse(st, eff, NULL);		VS3D_ResetClipPlane(eff->surface);	} else {		grouping_traverse(st, eff, NULL);	}	eff->num_clip_planes--;}void R3D_InitPlaneClipper(Render3D *sr, GF_Node *node){	PlaneClipper pc;	if (PlaneClipper_GetNode(node, &pc)) {		GroupingNode *stack = (GroupingNode *)malloc(sizeof(GroupingNode));		SetupGroupingNode(stack, sr->compositor, node, & pc.children);		gf_node_set_private(node, stack);		gf_node_set_callback_function(node, RenderPlaneClipper);		/*we're a grouping node, force bounds rebuild as soon as loaded*/		gf_node_dirty_set(node, GF_SG_CHILD_DIRTY, 0);	}}/*hardcoded proto loading - this is mainly used for module development and testing...*/void R3D_InitHardcodedProto(Render3D *sr, GF_Node *node){	MFURL *proto_url;	GF_Proto *proto;	u32 i;	proto = gf_node_get_proto(node);	if (!proto) return;	proto_url = gf_sg_proto_get_extern_url(proto);	for (i=0; i<proto_url->count; i++) {		const char *url = proto_url->vals[0].url;		if (!strnicmp(url, "urn:inet:gpac:builtin:PathExtrusion", 22 + 13)) {			R3D_InitPathExtrusion(sr, node);			return;		}		if (!strnicmp(url, "urn:inet:gpac:builtin:PlanarExtrusion", 22 + 15)) {			R3D_InitPlanarExtrusion(sr, node);			return;		}		if (!strnicmp(url, "urn:inet:gpac:builtin:PlaneClipper", 22 + 12)) {			R3D_InitPlaneClipper(sr, node);			return;		}		if (!strnicmp(url, "urn:inet:gpac:builtin:TextureText", 22 + 11)) {			void R3D_InitTextureText(Render3D *sr, GF_Node *node);			R3D_InitTextureText(sr, node);			return;		}	}}

⌨️ 快捷键说明

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