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

📄 geometry_x3d.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			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"Bool Stack2DIntersectWithRay(GF_Node *owner, GF_Ray *r, SFVec3f *outPoint, SFVec3f *outNormal, SFVec2f *outTexCoords);static Bool R3D_NoIntersectionWithRay(GF_Node *owner, GF_Ray *ray, SFVec3f *vec, SFVec3f *outNormal, SFVec2f *outTexCoords){	return 0;}static Bool Disk2DIntersectWithRay(GF_Node *owner, GF_Ray *ray, SFVec3f *outPoint, SFVec3f *outNormal, SFVec2f *outTexCoords){	Fixed r, sqr, sqdist;	Bool inside;	if (!R3D_Get2DPlaneIntersection(ray, outPoint)) return 0;	sqdist = gf_mulfix(outPoint->x, outPoint->x) + gf_mulfix(outPoint->y, outPoint->y);	r = ((X_Disk2D *)owner)->outerRadius;	sqr = gf_mulfix(r, r);	inside = (sqr >= sqdist) ? 1 : 0;	if (!inside) return 0;	r = ((X_Disk2D *)owner)->innerRadius;	sqr = r*r;	inside = (sqr <= sqdist) ? 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 RenderDisk2D(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 = ((X_Disk2D *) node)->outerRadius * 2;		stack2D_reset(st);		/*FIXME - move to 3D stack and skip path stuff to enable it with OpenGL-ES*/		gf_path_add_ellipse(st->path, 0, 0, a, a);		a = ((X_Disk2D *) node)->innerRadius * 2;		if (a) gf_path_add_ellipse(st->path, 0, 0, a, a);		mesh_from_path(st->mesh, st->path);		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_InitDisk2D(Render3D *sr, GF_Node *node){	stack2D *st = BaseStack2D(sr->compositor, node);	gf_node_set_callback_function(node, RenderDisk2D);	st->IntersectWithRay = Disk2DIntersectWithRay;}static void RenderArc2D(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)) {		stack2D_reset(st);		if (gf_node_get_tag(node)==TAG_X3D_Arc2D) {			X_Arc2D *a = (X_Arc2D *) node;			gf_path_add_arc(st->path, a->radius, a->startAngle, a->endAngle, 0);			mesh_get_outline(st->mesh, st->path);		} else {			X_ArcClose2D *a = (X_ArcClose2D *) node;			gf_path_add_arc(st->path, a->radius, a->startAngle, a->endAngle, !stricmp(a->closureType.buffer, "PIE") ? 2 : 1);			mesh_from_path(st->mesh, st->path);		}		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_InitArc2D(Render3D *sr, GF_Node *node){	stack2D *st = BaseStack2D(sr->compositor, node);	gf_node_set_callback_function(node, RenderArc2D);	if (gf_node_get_tag(node)==TAG_X3D_Arc2D) {		st->IntersectWithRay = R3D_NoIntersectionWithRay;	} else {		st->IntersectWithRay = Stack2DIntersectWithRay;	}}static void RenderPolyline2D(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)) {		u32 i;		X_Polyline2D *a = (X_Polyline2D *) node;		stack2D_reset(st);		for (i=0; i<a->lineSegments.count; i++) {			if (i) {				gf_path_add_line_to(st->path, a->lineSegments.vals[i].x, a->lineSegments.vals[i].y);			} else {				gf_path_add_move_to(st->path, a->lineSegments.vals[i].x, a->lineSegments.vals[i].y);			}		}		mesh_get_outline(st->mesh, st->path);		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_InitPolyline2D(Render3D *sr, GF_Node *node){	stack2D *st = BaseStack2D(sr->compositor, node);	gf_node_set_callback_function(node, RenderPolyline2D);	st->IntersectWithRay = R3D_NoIntersectionWithRay;}static void RenderPolypoint2D(GF_Node *node, void *rs, Bool is_destroy){	SFColorRGBA col;	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)) {		u32 i;		X_Polypoint2D *p = (X_Polypoint2D *)node;		mesh_reset(st->mesh);		st->mesh->mesh_type = MESH_POINTSET;		col.red = col.green = col.blue = 0; col.alpha = FIX_ONE;		for (i=0; i<p->point.count; i++) {			mesh_set_point(st->mesh, p->point.vals[i].x, p->point.vals[i].y, 0, col);			mesh_set_index(st->mesh, st->mesh->v_count-1);		}		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;}void R3D_InitPolypoint2D(Render3D *sr, GF_Node *node){	DrawableStack *st = BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderPolypoint2D);	st->IntersectWithRay = R3D_NoIntersectionWithRay;}static void RenderLineSet(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)) {		u32 i, j, c_idx;		GenMFField *cols;		GF_Vertex vx;		Bool rgba_col;		X_LineSet *p = (X_LineSet *)node;		X_Coordinate *c = (X_Coordinate *) p->coord;		gf_node_dirty_clear(node, 0);		mesh_reset(st->mesh);		st->mesh->mesh_type = MESH_LINESET;		cols = NULL;		rgba_col = 0;		if (p->color) {			if (gf_node_get_tag(p->color)==TAG_X3D_ColorRGBA) {				rgba_col = 1;				cols = (GenMFField *) & ((X_ColorRGBA *) p->color)->color;			} else {				cols = (GenMFField *) & ((M_Color *) p->color)->color;			}		}		c_idx = 0;		memset(&vx, 0, sizeof(GF_Vertex));		for (i=0; i<p->vertexCount.count; i++) {			if (p->vertexCount.vals[i]<2) continue;			for (j=0; j<(u32) p->vertexCount.vals[i]; j++) {				vx.pos = c->point.vals[c_idx];				if (cols && (cols->count>c_idx)) {					if (rgba_col) {						vx.color = ((MFColorRGBA *)cols)->vals[c_idx];					} else {						vx.color = gf_sg_sfcolor_to_rgba( ((MFColor *)cols)->vals[c_idx]);					}				}				mesh_set_vertex_vx(st->mesh, &vx);				if (j) {					mesh_set_index(st->mesh, st->mesh->v_count-2);					mesh_set_index(st->mesh, st->mesh->v_count-1);				}				c_idx++;				if (c_idx==c->point.count) break;			}		}		if (cols) st->mesh->flags |= MESH_HAS_COLOR;		mesh_update_bounds(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_InitLineSet(Render3D *sr, GF_Node *node){	DrawableStack *st = BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderLineSet);	st->IntersectWithRay = R3D_NoIntersectionWithRay;}static void RenderTriangleSet2D(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)) {		u32 i, count, idx;		GF_Vertex v1, v2, v3;		X_TriangleSet2D *p = (X_TriangleSet2D *)node;		mesh_reset(st->mesh);		st->mesh->mesh_type = MESH_TRIANGLES;		v1.color.red = v1.color.green = v1.color.blue = 0;		v1.normal.x = v1.normal.y = 0; v1.normal.z = FIX_ONE;		v1.pos.z = 0;		v3 = v2 = v1;		count = p->vertices.count;		while (count%3) count--;		for (i=0; i<count; i+=3) {			idx = st->mesh->v_count;			v1.pos.x = p->vertices.vals[i].x;			v1.pos.y = p->vertices.vals[i].y;			v2.pos.x = p->vertices.vals[i+1].x;			v2.pos.y = p->vertices.vals[i+1].y;			v3.pos.x = p->vertices.vals[i+2].x;			v3.pos.y = p->vertices.vals[i+2].y;			mesh_set_vertex_vx(st->mesh, &v1);			mesh_set_vertex_vx(st->mesh, &v2);			mesh_set_vertex_vx(st->mesh, &v3);			gf_vec_diff(v2.pos, v2.pos, v1.pos);			gf_vec_diff(v3.pos, v3.pos, v1.pos);			v1.pos = gf_vec_cross(v2.pos, v3.pos);			if (v1.pos.z<0) {				mesh_set_triangle(st->mesh, idx, idx+2, idx+1);			} else {				mesh_set_triangle(st->mesh, idx, idx+1, idx+2);			}		}		st->mesh->flags |= MESH_IS_2D;		mesh_update_bounds(st->mesh);		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;}void R3D_InitTriangleSet2D(Render3D *sr, GF_Node *node){	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderTriangleSet2D);}static void BuildTriangleSet(GF_Mesh *mesh, GF_Node *_coords, GF_Node *_color, GF_Node *_txcoords, GF_Node *_normal, MFInt32 *indices, Bool normalPerVertex, Bool ccw, Bool solid){	u32 i, count, 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;		}	}	if (indices) {		count = indices->count;	} else {		count = c->point.count;	}	while (count%3) count--;	memset(&vx, 0, sizeof(GF_Vertex));	for (i=0; i<count; i++) {		u32 idx;		if (indices) {			if (indices->count<=i) return;			idx = indices->vals[i];		} else {			idx = i;		}		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]);			}		}		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 (i%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);	}	for (i=0; i<mesh->v_count; i+=3) {		mesh_set_triangle(mesh, i, i+1, i+2);	}	if (generate_tx) mesh_generate_tex_coords(mesh, _txcoords);	if (!ccw) mesh->flags |= MESH_IS_CW;	if (cols) mesh->flags |= MESH_HAS_COLOR;	if (rgba_col) mesh->flags |= MESH_HAS_ALPHA;	if (!_normal) mesh_recompute_normals(mesh);	if (solid) mesh->flags |= MESH_IS_SOLID;	mesh_update_bounds(mesh);	gf_mesh_build_aabbtree(mesh);}static void RenderTriangleSet(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_TriangleSet *ts = (X_TriangleSet *)node;		gf_node_dirty_clear(node, 0);		if (!ts->coord) return;		BuildTriangleSet(st->mesh, ts->coord, ts->color, ts->texCoord, ts->normal, NULL, ts->normalPerVertex, ts->ccw, ts->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_InitTriangleSet(Render3D *sr, GF_Node *node){	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderTriangleSet);}static void RenderIndexedTriangleSet(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_IndexedTriangleSet *its = (X_IndexedTriangleSet *)node;		gf_node_dirty_clear(node, 0);		if (!its->coord) return;		BuildTriangleSet(st->mesh, its->coord, its->color, its->texCoord, its->normal, &its->index, its->normalPerVertex, its->ccw, its->solid);	}	if (!eff->traversing_mode) {		VS_DrawMesh(eff, st->mesh);	} else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		eff->bbox = st->mesh->bounds;	}}static void ITS_SetIndex(GF_Node *node){	X_IndexedTriangleSet *its = (X_IndexedTriangleSet*)node;	gf_sg_vrml_field_copy(&its->index, &its->set_index, GF_SG_VRML_MFINT32);	gf_sg_vrml_mf_reset(&its->set_index, GF_SG_VRML_MFINT32);}void R3D_InitIndexedTriangleSet(Render3D *sr, GF_Node *node){	X_IndexedTriangleSet *its = (X_IndexedTriangleSet*)node;	BaseDrawableStack(sr->compositor, node);	gf_node_set_callback_function(node, RenderIndexedTriangleSet);	its->on_set_index = ITS_SetIndex;}static void BuildTriangleStripSet(GF_Mesh *mesh, GF_Node *_coords, GF_Node *_color, GF_Node *_txcoords, GF_Node *_normal, MFInt32 *stripList, MFInt32 *indices, Bool normalPerVertex, Bool ccw, Bool solid)

⌨️ 快捷键说明

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