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

📄 geometry_stacks.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *			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 "visual_surface.h"#include <gpac/options.h>/*		Shape */static void RenderShape(GF_Node *node, void *rs, Bool is_destroy){	DrawableStack *st;	u32 cull_bckup;	RenderEffect3D *eff; 	M_Shape *shape;	if (is_destroy) return;	eff = (RenderEffect3D *) rs;	if (eff->traversing_mode==TRAVERSE_LIGHTING) return;	shape = (M_Shape *) node;	if (!shape->geometry) return;	eff->appear = (GF_Node *) shape->appearance;	/*reset this node dirty flag (because bitmap may trigger bounds invalidation on the fly)*/	gf_node_dirty_clear(node, 0);	/*check traverse mode, and take care of switch-off flag*/	if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		/*this is done regardless of switch flag*/		gf_node_render((GF_Node *) shape->geometry, eff);		/*reset appearance dirty flag to get sure size changes in textures invalidates the parent graph(s)*/		gf_node_dirty_clear(eff->appear, 0);		eff->appear = NULL;	} else {		if (eff->trav_flags & GF_SR_TRAV_SWITCHED_OFF) return;		/*if we're here we passed culler already*/		if (eff->traversing_mode==TRAVERSE_RENDER) 			gf_node_render((GF_Node *) shape->geometry, eff);		else if (eff->traversing_mode==TRAVERSE_SORT) {			st = (DrawableStack*)gf_node_get_private(shape->geometry);			cull_bckup = eff->cull_flag;			if (st && node_cull(eff, &st->mesh->bounds, 0)) {				gf_node_allow_cyclic_render(node);				VS_RegisterContext(eff, node, &st->mesh->bounds, 1);			}			eff->cull_flag = cull_bckup;		}		else if (eff->traversing_mode==TRAVERSE_PICK) drawable_do_pick(shape->geometry, eff);		else if (eff->traversing_mode==TRAVERSE_COLLIDE) drawable_do_collide(shape->geometry, eff);	}}Bool R3D_Get2DPlaneIntersection(GF_Ray *ray, SFVec3f *res){	GF_Plane p;	Fixed t, t2;	p.normal.x = p.normal.y = 0; p.normal.z = FIX_ONE;	p.d = 0;	t2 = gf_vec_dot(p.normal, ray->dir);	if (t2 == 0) return 0;	t = - gf_divfix(gf_vec_dot(p.normal, ray->orig) + p.d, t2);	if (t<0) return 0;	*res = gf_vec_scale(ray->dir, t);	gf_vec_add(*res, ray->orig, *res);	return 1;}Bool R3D_PickInClipper(RenderEffect3D *eff, GF_Rect *clip){	SFVec3f pos;	GF_Matrix mx;	GF_Ray r;	gf_mx_copy(mx, eff->model_matrix);	gf_mx_inverse(&mx);	r = eff->ray;	gf_mx_apply_ray(&mx, &r);	if (!R3D_Get2DPlaneIntersection(&r, &pos)) return 0;	if ( (pos.x < clip->x) || (pos.y > clip->y) 		|| (pos.x > clip->x + clip->width) || (pos.y < clip->y - clip->height) ) return 0;	return 1;}void R3D_InitShape(Render3D *sr, GF_Node *node){	gf_node_set_callback_function(node, RenderShape);}static Bool R3D_NoIntersectionWithRay(GF_Node *owner, GF_Ray *ray, SFVec3f *vec, SFVec3f *outNormal, SFVec2f *outTexCoords){	return 0;}static void RenderBox(GF_Node *n, void *rs, Bool is_destroy){	RenderEffect3D *eff = (RenderEffect3D *)rs;	DrawableStack *st = (DrawableStack*)gf_node_get_private(n);	M_Box *box = (M_Box *)n;	if (is_destroy) {		drawable_node_destroy(n);		return;	}	if (gf_node_dirty_get(n)) {		mesh_new_box(st->mesh, box->size);		gf_node_dirty_clear(n, 0);	}	if (!eff->traversing_mode) {		VS_DrawMesh(eff, st->mesh);	}	else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}void R3D_InitBox(Render3D *sr, GF_Node *node){	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderBox);}static void RenderCone(GF_Node *n, void *rs, Bool is_destroy){	RenderEffect3D *eff = (RenderEffect3D *)rs;	DrawableStack *st = (DrawableStack*)gf_node_get_private(n);	M_Cone *co = (M_Cone *)n;	if (is_destroy) {		drawable_node_destroy(n);		return;	}	if (gf_node_dirty_get(n)) {		mesh_new_cone(st->mesh, co->height, co->bottomRadius, co->bottom, co->side, eff->surface->render->compositor->high_speed);		gf_node_dirty_clear(n, 0);	}	if (!eff->traversing_mode) {		VS_DrawMesh(eff, st->mesh);	}	else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}void R3D_InitCone(Render3D *sr, GF_Node *node){	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderCone);}static void RenderCylinder(GF_Node *n, void *rs, Bool is_destroy){	RenderEffect3D *eff = (RenderEffect3D *)rs;	DrawableStack *st = (DrawableStack*)gf_node_get_private(n);	M_Cylinder *cy = (M_Cylinder *)n;	if (is_destroy) {		drawable_node_destroy(n);		return;	}	if (gf_node_dirty_get(n) ) {		mesh_new_cylinder(st->mesh, cy->height, cy->radius, cy->bottom, cy->side, cy->top, eff->surface->render->compositor->high_speed);		gf_node_dirty_clear(n, 0);	}	if (!eff->traversing_mode) {		VS_DrawMesh(eff, st->mesh);	}	else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}void R3D_InitCylinder(Render3D *sr, GF_Node *node){	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderCylinder);}static void RenderSphere(GF_Node *n, void *rs, Bool is_destroy){	RenderEffect3D *eff = (RenderEffect3D *)rs;	DrawableStack *st = (DrawableStack*)gf_node_get_private(n);	M_Sphere *sp = (M_Sphere *)n;	if (is_destroy) {		drawable_node_destroy(n);		return;	}	if (gf_node_dirty_get(n)) {		mesh_new_sphere(st->mesh, sp->radius, eff->surface->render->compositor->high_speed);		gf_node_dirty_clear(n, 0);	}	if (!eff->traversing_mode) {		VS_DrawMesh(eff, st->mesh);	}	else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}void R3D_InitSphere(Render3D *sr, GF_Node *node){	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderSphere);}static Bool CircleIntersectWithRay(GF_Node *owner, GF_Ray *ray, SFVec3f *outPoint, SFVec3f *outNormal, SFVec2f *outTexCoords){	Fixed r, sqr;	Bool inside;	if (!R3D_Get2DPlaneIntersection(ray, outPoint)) return 0;	r = ((M_Circle *)owner)->radius;	sqr = gf_mulfix(r, r);	inside = (sqr >= gf_mulfix(outPoint->x, outPoint->x) + gf_mulfix(outPoint->y, outPoint->y)) ? 1 : 0;	if (!inside) return 0;	if (outNormal) { outNormal->x = outNormal->y = 0; outNormal->z = FIX_ONE; }	if (outTexCoords) { 		outTexCoords->x = gf_divfix(outPoint->x, r) + FIX_ONE/2;		outTexCoords->y = gf_divfix(outPoint->y, r) + FIX_ONE/2;	}	return 1;}static void RenderCircle(GF_Node *node, void *rs, Bool is_destroy){	stack2D *st = (stack2D *)gf_node_get_private(node);	RenderEffect3D *eff = (RenderEffect3D *)rs;	if (is_destroy) {		stack2D_node_predestroy(node);		return;	}	if (gf_node_dirty_get(node)) {		Fixed a = ((M_Circle *) node)->radius * 2;		stack2D_reset(st);		gf_path_add_ellipse(st->path, 0, 0, a, a);		mesh_new_ellipse(st->mesh, a, a, eff->surface->render->compositor->high_speed);		gf_node_dirty_clear(node, 0);	}	if (!eff->traversing_mode) {		stack2D_draw(st, eff);	} else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) 		eff->bbox = st->mesh->bounds;}void R3D_InitCircle(Render3D *sr, GF_Node *node){	stack2D *st = BaseStack2D(sr->compositor, node);	gf_node_set_callback_function(node, RenderCircle);	st->IntersectWithRay = CircleIntersectWithRay;}static Bool EllipseIntersectWithRay(GF_Node *owner, GF_Ray *ray, SFVec3f *outPoint, SFVec3f *outNormal, SFVec2f *outTexCoords){	Fixed a, b;	Bool inside;	if (!R3D_Get2DPlaneIntersection(ray, outPoint)) return 0;	a = ((M_Ellipse *)owner)->radius.x; a = gf_mulfix(a, a);	b = ((M_Ellipse *)owner)->radius.y; b = gf_mulfix(b, b);	inside = (gf_muldiv(outPoint->x, outPoint->x, a) + gf_muldiv(outPoint->y, outPoint->y, b) <= 1) ? 1 : 0;	if (!inside) return 0;	if (outNormal) { outNormal->x = outNormal->y = 0; outNormal->z = FIX_ONE; }	if (outTexCoords) { 		outTexCoords->x = gf_divfix(outPoint->x, a) + FIX_ONE/2;		outTexCoords->y = gf_divfix(outPoint->y, b) + FIX_ONE/2;	}	return 1;}static void RenderEllipse(GF_Node *node, void *rs, Bool is_destroy){	stack2D *st = (stack2D *)gf_node_get_private(node);	RenderEffect3D *eff = (RenderEffect3D *)rs;	if (is_destroy) {		stack2D_node_predestroy(node);		return;	}	if (gf_node_dirty_get(node)) {		Fixed a = ((M_Ellipse *) node)->radius.x;		Fixed b = ((M_Ellipse *) node)->radius.y;		stack2D_reset(st);		gf_path_add_ellipse(st->path, 0, 0, a, b);		mesh_new_ellipse(st->mesh, a, b, eff->surface->render->compositor->high_speed);		gf_node_dirty_clear(node, 0);	}	if (!eff->traversing_mode) 		stack2D_draw(st, eff);	else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) 		eff->bbox = st->mesh->bounds;}void R3D_InitEllipse(Render3D *sr, GF_Node *node){	stack2D *st = BaseStack2D(sr->compositor, node);	gf_node_set_callback_function(node, RenderEllipse);	st->IntersectWithRay = EllipseIntersectWithRay;}static Bool RectangleIntersectWithRay(GF_Node *owner, GF_Ray *ray, SFVec3f *outPoint, SFVec3f *outNormal, SFVec2f *outTexCoords){	stack2D *st;	Bool inside;	if (!R3D_Get2DPlaneIntersection(ray, outPoint)) return 0;	st = (stack2D *) gf_node_get_private(owner);	inside = ( (outPoint->x >= st->mesh->bounds.min_edge.x) && (outPoint->y >= st->mesh->bounds.min_edge.y) 			&& (outPoint->x <= st->mesh->bounds.max_edge.x) && (outPoint->y <= st->mesh->bounds.max_edge.y) 			) ? 1 : 0;	if (!inside) return 0;	if (outNormal) { outNormal->x = outNormal->y = 0; outNormal->z = FIX_ONE; }	if (outTexCoords) { 		outTexCoords->x = gf_divfix(outPoint->x, ((M_Rectangle*)owner)->size.x) + FIX_ONE/2;		outTexCoords->y = gf_divfix(outPoint->y, ((M_Rectangle*)owner)->size.y) + FIX_ONE/2;	}	return 1;}static void RenderRectangle(GF_Node *node, void *rs, Bool is_destroy){	stack2D *st = (stack2D *) gf_node_get_private(node);	RenderEffect3D *eff = (RenderEffect3D *)rs;	if (is_destroy) {		stack2D_node_predestroy(node);		return;	}	/*build vec path*/	if (gf_node_dirty_get(node)) {		SFVec2f s = ((M_Rectangle *) node)->size;		stack2D_reset(st);		gf_path_add_rect_center(st->path, 0, 0, s.x, s.y);		mesh_new_rectangle(st->mesh, s);		gf_node_dirty_clear(node, 0);	}	if (!eff->traversing_mode) 		stack2D_draw(st, eff);	else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) 		eff->bbox = st->mesh->bounds;}void R3D_InitRectangle(Render3D *sr, GF_Node *node){	stack2D *st = BaseStack2D(sr->compositor, node);	gf_node_set_callback_function(node, RenderRectangle);	st->IntersectWithRay = RectangleIntersectWithRay;}Bool Stack2DIntersectWithRay(GF_Node *owner, GF_Ray *r, SFVec3f *outPoint, SFVec3f *outNormal, SFVec2f *outTexCoords){	Bool inside;	stack2D *st;	if (!R3D_Get2DPlaneIntersection(r, outPoint)) return 0;	st = (stack2D *) gf_node_get_private(owner);	if ( (outPoint->x < st->mesh->bounds.min_edge.x) || (outPoint->y < st->mesh->bounds.min_edge.y) 			|| (outPoint->x > st->mesh->bounds.max_edge.x) || (outPoint->y > st->mesh->bounds.max_edge.y) ) return 0;	inside = gf_path_point_over(st->path, outPoint->x, outPoint->y);	if (!inside) return 0;	if (outNormal) { outNormal->x = outNormal->y = 0; outNormal->z = FIX_ONE; }	if (outTexCoords) { 		outTexCoords->x = gf_divfix(outPoint->x, (st->mesh->bounds.max_edge.x - st->mesh->bounds.min_edge.x)) + FIX_ONE/2;		outTexCoords->y = gf_divfix(outPoint->y, (st->mesh->bounds.max_edge.y - st->mesh->bounds.min_edge.y)) + FIX_ONE/2;	}	return 1;}//#define CHECK_VALID_C2D(nbPts) if (cur_index+nbPts>=pt_count) { gf_path_reset(st->path); return; }#define CHECK_VALID_C2D(nbPts)static void build_curve2D(stack2D *st, M_Curve2D *c2D){	SFVec2f orig, ct_orig, ct_end, end;	u32 cur_index, i, remain, type_count, pt_count;	SFVec2f *pts;	M_Coordinate2D *coord = (M_Coordinate2D *)c2D->point;

⌨️ 快捷键说明

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