Exemplo n.º 1
0
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;
	SFColorRGBA rgba;
	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_COMPOSE, ("[X3D] 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) {
					rgba = ((MFColorRGBA *)cols)->vals[idx];
				} else {
					rgba = gf_sg_sfcolor_to_rgba( ((MFColor *)cols)->vals[idx]);
				}
				vx.color = MESH_MAKE_COL(rgba);
			}
			/*according to X3D spec, if normal field is set, it is ALWAYS as normal per vertex*/
			if (norms && (norms->count>idx)) {
				SFVec3f n = norms->vals[idx];
				gf_vec_norm(&n);
				MESH_SET_NORMAL(vx, n);
			}
			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*/
				MESH_GET_NORMAL(n_0, mesh->vertices[mesh->indices[3*cur_face]]);
				n_tot = n_0;
				cur_face++;
				nb_face = fanList->vals[fan] - 2;
				for (i=1; i<nb_face; i++) {
					MESH_GET_NORMAL(n_1, mesh->vertices[mesh->indices[3*cur_face + 1]]);
					gf_vec_add(n_avg, n_0, n_1);
					gf_vec_norm(&n_avg);
					MESH_SET_NORMAL(mesh->vertices[mesh->indices[3*cur_face + 1]], 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_SET_NORMAL(mesh->vertices[mesh->indices[3*(i+start_face)]], n_tot);
				}
			}
		}
	}
	if (solid) mesh->flags |= MESH_IS_SOLID;
	mesh_update_bounds(mesh);
	gf_mesh_build_aabbtree(mesh);
}
Exemplo n.º 2
0
static void DrawBackground2D_3D(M_Background2D *bck, Background2DStack *st, GF_TraverseState *tr_state)
{
	GF_Matrix mx;
	Bool use_texture;

	use_texture = back_texture_enabled(bck, &st->txh);

	visual_3d_set_background_state(tr_state->visual, 1);

	visual_3d_matrix_push(tr_state->visual);

/*	visual_3d_set_matrix_mode(tr_state->visual, V3D_MATRIX_TEXTURE);
	gf_sc_texture_get_transform(&st->txh, NULL, &mx, 0);
	visual_3d_matrix_load(tr_state->visual, mx.m);
*/	
	visual_3d_set_matrix_mode(tr_state->visual, V3D_MATRIX_MODELVIEW);

	/*little opt: if we clear the main visual clear it entirely */
	if (! tr_state->is_layer) {
		visual_3d_clear(tr_state->visual, bck->backColor, FIX_ONE);
		if (!use_texture) {
			visual_3d_matrix_pop(tr_state->visual);
			visual_3d_set_background_state(tr_state->visual, 0);
			return;
		}
		/*we need a hack here because main vp is always traversed before main background, and in the case of a
		2D viewport it modifies the modelview matrix, which we don't want ...*/
		visual_3d_matrix_reset(tr_state->visual);
	}
	if (!use_texture || (!tr_state->is_layer && st->txh.transparent) ) visual_3d_set_material_2d(tr_state->visual, bck->backColor, FIX_ONE);
	if (use_texture) {
		visual_3d_set_state(tr_state->visual, V3D_STATE_COLOR, ! tr_state->is_layer);
		tr_state->mesh_num_textures = gf_sc_texture_enable(&st->txh, NULL);
		if (!tr_state->mesh_num_textures) visual_3d_set_material_2d(tr_state->visual, bck->backColor, FIX_ONE);
	}

	/*create mesh object if needed*/
	if (!st->mesh) {
		st->mesh = new_mesh();
		mesh_set_vertex(st->mesh, -B2D_PLANE_HSIZE, -B2D_PLANE_HSIZE, 0,  0,  0,  FIX_ONE, 0, 0);
		mesh_set_vertex(st->mesh,  B2D_PLANE_HSIZE, -B2D_PLANE_HSIZE, 0,  0,  0,  FIX_ONE, FIX_ONE, 0);
		mesh_set_vertex(st->mesh,  B2D_PLANE_HSIZE,  B2D_PLANE_HSIZE, 0,  0,  0,  FIX_ONE, FIX_ONE, FIX_ONE);
		mesh_set_vertex(st->mesh, -B2D_PLANE_HSIZE,  B2D_PLANE_HSIZE, 0,  0,  0,  FIX_ONE, 0, FIX_ONE);
		mesh_set_triangle(st->mesh, 0, 1, 2); mesh_set_triangle(st->mesh, 0, 2, 3);
		st->mesh->flags |= MESH_IS_2D;
	}

	gf_mx_init(mx);
	if (tr_state->camera->is_3D) {
		Fixed sx, sy;
		/*reset matrix*/
		visual_3d_matrix_reset(tr_state->visual);
		sx = sy = 2 * gf_mulfix(gf_tan(tr_state->camera->fieldOfView/2), tr_state->camera->z_far);
		if (tr_state->camera->width > tr_state->camera->height) {
			sx = gf_muldiv(sx, tr_state->camera->width, tr_state->camera->height);
		} else {
			sy = gf_muldiv(sy, tr_state->camera->height, tr_state->camera->width);
		}
		gf_mx_add_scale(&mx, sx, sy, FIX_ONE);
#ifdef GPAC_FIXED_POINT
		gf_mx_add_translation(&mx, 0, 0, - (tr_state->camera->z_far/100)*99);
#else
		gf_mx_add_translation(&mx, 0, 0, -0.995f*tr_state->camera->z_far);
#endif
	} else {
		gf_mx_add_scale(&mx, tr_state->bbox.max_edge.x - tr_state->bbox.min_edge.x, 
							tr_state->bbox.max_edge.y - tr_state->bbox.min_edge.y,
							FIX_ONE);
		/*when in layer2D, DON'T MOVE BACKGROUND TO ZFAR*/
		if (!tr_state->is_layer) {
			Fixed tr;
#ifdef GPAC_FIXED_POINT
			tr = -(tr_state->camera->z_far/100)*99;
#else
			tr = -0.999f*tr_state->camera->z_far;
#endif
			if (!tr_state->camera->is_3D) tr = -tr;
			gf_mx_add_translation(&mx, 0, 0, tr);
		}
	}
	visual_3d_matrix_add(tr_state->visual, mx.m);
	visual_3d_mesh_paint(tr_state, st->mesh);
	if (tr_state->mesh_num_textures) {
		gf_sc_texture_disable(&st->txh);
		tr_state->mesh_num_textures = 0;
	}

	visual_3d_matrix_pop(tr_state->visual);
	visual_3d_set_background_state(tr_state->visual, 0);
}
Exemplo n.º 3
0
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)
{
	u32 strip, i, cur_idx, generate_tx;
	GF_Vertex vx;
	GenMFField *cols;
	MFVec3f *norms;
	MFVec2f *txcoords;
	Bool rgba_col;
	SFColorRGBA rgba;
	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_COMPOSE, ("[X3D] 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) {
					rgba = ((MFColorRGBA *)cols)->vals[idx];
				} else {
					rgba = gf_sg_sfcolor_to_rgba( ((MFColor *)cols)->vals[idx]);
				}
				vx.color = MESH_MAKE_COL(rgba);
			}
			/*according to X3D spec, if normal field is set, it is ALWAYS as normal per vertex*/
			if (norms && (norms->count>idx)) {
				SFVec3f n = norms->vals[idx];
				gf_vec_norm(&n);
				MESH_SET_NORMAL(vx, n);
			}
			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;
				MESH_GET_NORMAL(v, mesh->vertices[mesh->indices[i]]);
				v = gf_vec_scale(v,-1);
				MESH_SET_NORMAL(mesh->vertices[mesh->indices[i]], v);
				mesh->vertices[mesh->indices[i+1]].normal = mesh->vertices[mesh->indices[i]].normal;
				mesh->vertices[mesh->indices[i+2]].normal = mesh->vertices[mesh->indices[i]].normal;
				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*/
				MESH_GET_NORMAL(n_0, mesh->vertices[mesh->indices[3*cur_face]]);
				/*second face normal*/
				MESH_GET_NORMAL(n_1, mesh->vertices[mesh->indices[3*(cur_face+1)]]);

				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_SET_NORMAL(mesh->vertices[mesh->indices[3*cur_face+1]], n_avg);
				MESH_SET_NORMAL(mesh->vertices[mesh->indices[3*(cur_face+1)]], 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)*/
					MESH_GET_NORMAL(n_2, mesh->vertices[mesh->indices[3*cur_face + 1]]);
					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_SET_NORMAL(mesh->vertices[mesh->indices[3*cur_face - 1]], n_avg);
					/*second of current face*/
					mesh->vertices[mesh->indices[3*cur_face + 1]].normal = mesh->vertices[mesh->indices[3*cur_face - 1]].normal;
					/*first of next face*/
					mesh->vertices[mesh->indices[3*cur_face + 3]].normal = mesh->vertices[mesh->indices[3*cur_face - 1]].normal;
					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);
}
Exemplo n.º 4
0
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;
	SFColorRGBA rgba;
	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) {
				rgba = ((MFColorRGBA *)cols)->vals[idx];
			} else {
				rgba = gf_sg_sfcolor_to_rgba( ((MFColor *)cols)->vals[idx]);
			}
			vx.color = MESH_MAKE_COL(rgba);
		}
		if (norms && (norms->count>idx)) {
			SFVec3f n = norms->vals[idx];
			gf_vec_norm(&n);
			MESH_SET_NORMAL(vx, n);
		}
		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);
}
Exemplo n.º 5
0
static void TraverseTriangleSet2D(GF_Node *node, void *rs, Bool is_destroy)
{
	DrawableContext *ctx;
	Drawable *stack = (Drawable *)gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;

	if (is_destroy) {
		drawable_node_del(node);
		return;
	}

	triangleset2d_check_changes(node, stack, tr_state);

	switch (tr_state->traversing_mode) {
#ifndef GPAC_DISABLE_3D
	case TRAVERSE_DRAW_3D:
		if (!stack->mesh) {
			SFColorRGBA col;
			u32 i, count, idx;
			GF_Vertex v1, v2, v3;
			X_TriangleSet2D *p = (X_TriangleSet2D *)node;

			stack->mesh = new_mesh();
			stack->mesh->mesh_type = MESH_TRIANGLES;
			col.red = col.green = col.blue = 0;
			col.alpha = FIX_ONE;
			v1.color = MESH_MAKE_COL(col);
			v1.normal.x = v1.normal.y = 0;
			v1.normal.z = MESH_NORMAL_UNIT;
			v1.pos.z = 0;
			v3 = v2 = v1;
			count = p->vertices.count;
			while (count%3) count--;
			for (i=0; i<count; i+=3) {
				idx = stack->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(stack->mesh, &v1);
				mesh_set_vertex_vx(stack->mesh, &v2);
				mesh_set_vertex_vx(stack->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(stack->mesh, idx, idx+2, idx+1);
				} else {
					mesh_set_triangle(stack->mesh, idx, idx+1, idx+2);
				}
			}
			stack->mesh->flags |= MESH_IS_2D;
			mesh_update_bounds(stack->mesh);
		}
		visual_3d_draw_2d(stack, tr_state);
		return;
#endif
	case TRAVERSE_GET_BOUNDS:
		gf_path_get_bounds(stack->path, &tr_state->bounds);
		return;
	case TRAVERSE_PICK:
		vrml_drawable_pick(stack, tr_state);
		return;
	case TRAVERSE_SORT:
#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->type_3d) return;
#endif
		ctx = drawable_init_context_mpeg4(stack, tr_state);
		if (!ctx) return;
		drawable_finalize_sort(ctx, tr_state, NULL);
		return;
	}
}
Exemplo n.º 6
0
void compositor_init_background(GF_Compositor *compositor, GF_Node *node)
{
	BackgroundStack *ptr;
	GF_SAFEALLOC(ptr, BackgroundStack);

	ptr->compositor = compositor;
	ptr->reg_stacks = gf_list_new();
	((M_Background *)node)->on_set_bind = back_set_bind;

	gf_mx_init(ptr->current_mx);

	/*build texture cube*/
	ptr->front_mesh = new_mesh();
	mesh_set_vertex(ptr->front_mesh, -PLANE_HSIZE, -PLANE_HSIZE, -PLANE_HSIZE_LOW,  0,  0,  FIX_ONE, 0, 0);
	mesh_set_vertex(ptr->front_mesh,  PLANE_HSIZE, -PLANE_HSIZE, -PLANE_HSIZE_LOW,  0,  0,  FIX_ONE, FIX_ONE, 0);
	mesh_set_vertex(ptr->front_mesh,  PLANE_HSIZE,  PLANE_HSIZE, -PLANE_HSIZE_LOW,  0,  0,  FIX_ONE, FIX_ONE, FIX_ONE);
	mesh_set_vertex(ptr->front_mesh, -PLANE_HSIZE,  PLANE_HSIZE, -PLANE_HSIZE_LOW,  0,  0,  FIX_ONE, 0, FIX_ONE);
	mesh_set_triangle(ptr->front_mesh, 0, 1, 2);
	mesh_set_triangle(ptr->front_mesh, 0, 2, 3);
	mesh_update_bounds(ptr->front_mesh);

	ptr->back_mesh = new_mesh();
	mesh_set_vertex(ptr->back_mesh, -PLANE_HSIZE, -PLANE_HSIZE,  PLANE_HSIZE_LOW,  0,  0,  -FIX_ONE, FIX_ONE, 0);
	mesh_set_vertex(ptr->back_mesh,  PLANE_HSIZE, -PLANE_HSIZE,  PLANE_HSIZE_LOW,  0,  0,  -FIX_ONE, 0, 0);
	mesh_set_vertex(ptr->back_mesh,  PLANE_HSIZE,  PLANE_HSIZE,  PLANE_HSIZE_LOW,  0,  0,  -FIX_ONE, 0, FIX_ONE);
	mesh_set_vertex(ptr->back_mesh, -PLANE_HSIZE,  PLANE_HSIZE,  PLANE_HSIZE_LOW,  0,  0,  -FIX_ONE, FIX_ONE, FIX_ONE);
	mesh_set_triangle(ptr->back_mesh, 0, 1, 2);
	mesh_set_triangle(ptr->back_mesh, 0, 2, 3);
	mesh_update_bounds(ptr->back_mesh);

	ptr->top_mesh = new_mesh();
	mesh_set_vertex(ptr->top_mesh, -PLANE_HSIZE,  PLANE_HSIZE_LOW,  PLANE_HSIZE,  0,  -FIX_ONE,  0, 0, 0);
	mesh_set_vertex(ptr->top_mesh,  PLANE_HSIZE,  PLANE_HSIZE_LOW,  PLANE_HSIZE,  0,  -FIX_ONE,  0, 0, FIX_ONE);
	mesh_set_vertex(ptr->top_mesh,  PLANE_HSIZE,  PLANE_HSIZE_LOW, -PLANE_HSIZE,  0,  -FIX_ONE,  0, FIX_ONE, FIX_ONE);
	mesh_set_vertex(ptr->top_mesh, -PLANE_HSIZE,  PLANE_HSIZE_LOW, -PLANE_HSIZE,  0,  -FIX_ONE,  0, FIX_ONE, 0);
	mesh_set_triangle(ptr->top_mesh, 0, 1, 2);
	mesh_set_triangle(ptr->top_mesh, 0, 2, 3);
	mesh_update_bounds(ptr->top_mesh);

	ptr->bottom_mesh = new_mesh();
	mesh_set_vertex(ptr->bottom_mesh, -PLANE_HSIZE, -PLANE_HSIZE_LOW, -PLANE_HSIZE,  0, FIX_ONE,  0, FIX_ONE, FIX_ONE);
	mesh_set_vertex(ptr->bottom_mesh,  PLANE_HSIZE, -PLANE_HSIZE_LOW, -PLANE_HSIZE,  0, FIX_ONE,  0, FIX_ONE, 0);
	mesh_set_vertex(ptr->bottom_mesh,  PLANE_HSIZE, -PLANE_HSIZE_LOW,  PLANE_HSIZE,  0, FIX_ONE,  0, 0, 0);
	mesh_set_vertex(ptr->bottom_mesh, -PLANE_HSIZE, -PLANE_HSIZE_LOW,  PLANE_HSIZE,  0, FIX_ONE,  0, 0, FIX_ONE);
	mesh_set_triangle(ptr->bottom_mesh, 0, 1, 2);
	mesh_set_triangle(ptr->bottom_mesh, 0, 2, 3);
	mesh_update_bounds(ptr->bottom_mesh);

	ptr->left_mesh = new_mesh();
	mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW, -PLANE_HSIZE, -PLANE_HSIZE, FIX_ONE,  0,  0, FIX_ONE, 0);
	mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW, -PLANE_HSIZE,  PLANE_HSIZE, FIX_ONE,  0,  0, 0, 0);
	mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW,  PLANE_HSIZE,  PLANE_HSIZE, FIX_ONE,  0,  0, 0, FIX_ONE);
	mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW,  PLANE_HSIZE, -PLANE_HSIZE, FIX_ONE,  0,  0, FIX_ONE, FIX_ONE);
	mesh_set_triangle(ptr->left_mesh, 0, 1, 2);
	mesh_set_triangle(ptr->left_mesh, 0, 2, 3);
	mesh_update_bounds(ptr->left_mesh);

	ptr->right_mesh = new_mesh();
	mesh_set_vertex(ptr->right_mesh,  PLANE_HSIZE_LOW, -PLANE_HSIZE,  PLANE_HSIZE, -FIX_ONE,  0,  0, FIX_ONE, 0);
	mesh_set_vertex(ptr->right_mesh,  PLANE_HSIZE_LOW, -PLANE_HSIZE, -PLANE_HSIZE, -FIX_ONE,  0,  0, 0, 0);
	mesh_set_vertex(ptr->right_mesh,  PLANE_HSIZE_LOW,  PLANE_HSIZE, -PLANE_HSIZE, -FIX_ONE,  0,  0, 0, FIX_ONE);
	mesh_set_vertex(ptr->right_mesh,  PLANE_HSIZE_LOW,  PLANE_HSIZE,  PLANE_HSIZE, -FIX_ONE,  0,  0, FIX_ONE, FIX_ONE);
	mesh_set_triangle(ptr->right_mesh, 0, 1, 2);
	mesh_set_triangle(ptr->right_mesh, 0, 2, 3);
	mesh_update_bounds(ptr->right_mesh);


	gf_sc_texture_setup(&ptr->txh_back, compositor, node);
	ptr->txh_back.update_texture_fcnt = UpdateBackgroundTexture;
	gf_sc_texture_setup(&ptr->txh_front, compositor, node);
	ptr->txh_front.update_texture_fcnt = UpdateBackgroundTexture;
	gf_sc_texture_setup(&ptr->txh_top, compositor, node);
	ptr->txh_top.update_texture_fcnt = UpdateBackgroundTexture;
	gf_sc_texture_setup(&ptr->txh_bottom, compositor, node);
	ptr->txh_bottom.update_texture_fcnt = UpdateBackgroundTexture;
	gf_sc_texture_setup(&ptr->txh_left, compositor, node);
	ptr->txh_left.update_texture_fcnt = UpdateBackgroundTexture;
	gf_sc_texture_setup(&ptr->txh_right, compositor, node);
	ptr->txh_right.update_texture_fcnt = UpdateBackgroundTexture;

	gf_node_set_private(node, ptr);
	gf_node_set_callback_function(node, TraverseBackground);

}
Exemplo n.º 7
0
static void back_build_dome(GF_Mesh *mesh, MFFloat *angles, MFColor *color, Bool ground_dome)
{
	u32 i, j, last_idx, ang_idx, new_idx;
	Bool pad;
	u32 step_div_h;
	GF_Vertex vx;
	SFColorRGBA start_col, end_col, fcol;
	Fixed start_angle, next_angle, angle, r, frac, first_angle;

	start_angle = 0;
	mesh_reset(mesh);

	start_col.red = start_col.green = start_col.blue = 0;
	end_col = start_col;
	if (color->count) {
		COL_TO_RGBA(start_col, color->vals[0]);
		end_col = start_col;
		if (color->count>1) COL_TO_RGBA(end_col, color->vals[1]);
	}

	start_col.alpha = end_col.alpha = FIX_ONE;
	vx.texcoords.x = vx.texcoords.y = 0;
	vx.color = MESH_MAKE_COL(start_col);
	vx.pos.x = vx.pos.z = 0;
	vx.pos.y = FIX_ONE;
	vx.normal.x = vx.normal.z = 0;
	vx.normal.y = -MESH_NORMAL_UNIT;

	mesh_set_vertex_vx(mesh, &vx);
	last_idx = 0;
	ang_idx = 0;

	pad = 1;
	next_angle = first_angle = 0;
	if (angles->count) {
		next_angle = angles->vals[0];
		first_angle = 7*next_angle/8;
		pad = 0;
	}

	step_div_h = DOME_STEP_H;
	i=0;
	if (ground_dome) {
		step_div_h *= 2;
		i=1;
	}

	for (; i<DOME_STEP_V; i++) {
		if (ground_dome) {
			angle = first_angle + (i * (GF_PI2-first_angle) / DOME_STEP_V);
		} else {
			angle = (i * GF_PI / DOME_STEP_V);
		}

		/*switch cols*/
		if (angle >= next_angle) {
			if (ang_idx+1<=angles->count) {
				start_angle = next_angle;
				next_angle = angles->vals[ang_idx+1];
				if (next_angle>GF_PI) next_angle=GF_PI;
				start_col = end_col;
				ang_idx++;
				if (ang_idx+1<color->count) {
					COL_TO_RGBA(end_col, color->vals[ang_idx+1]);
				} else {
					pad = 1;
				}
			} else {
				if (ground_dome) break;
				pad = 1;
			}
		}

		if (pad) {
			fcol = end_col;
		} else {
			frac = gf_divfix(angle - start_angle, next_angle - start_angle) ;
			fcol.red = gf_mulfix(end_col.red - start_col.red, frac) + start_col.red;
			fcol.green = gf_mulfix(end_col.green - start_col.green, frac) + start_col.green;
			fcol.blue = gf_mulfix(end_col.blue - start_col.blue, frac) + start_col.blue;
			fcol.alpha = FIX_ONE;
		}
		vx.color = MESH_MAKE_COL(fcol);

		vx.pos.y = gf_sin(GF_PI2 - angle);
		r = gf_sqrt(FIX_ONE - gf_mulfix(vx.pos.y, vx.pos.y));

		new_idx = mesh->v_count;
		for (j = 0; j < step_div_h; j++) {
			SFVec3f n;
			Fixed lon = 2 * GF_PI * j / step_div_h;
			vx.pos.x = gf_mulfix(gf_sin(lon), r);
			vx.pos.z = gf_mulfix(gf_cos(lon), r);
			n = gf_vec_scale(vx.pos, FIX_ONE /*-FIX_ONE*/);
			gf_vec_norm(&n);
			MESH_SET_NORMAL(vx, n);
			mesh_set_vertex_vx(mesh, &vx);

			if (j) {
				if (i>1) {
					mesh_set_triangle(mesh, last_idx+j, new_idx+j, new_idx+j-1);
					mesh_set_triangle(mesh, last_idx+j, new_idx+j-1, last_idx+j-1);
				} else {
					mesh_set_triangle(mesh, 0, new_idx+j, new_idx+j-1);
				}
			}
		}
		if (i>1) {
			mesh_set_triangle(mesh, last_idx, new_idx, new_idx+step_div_h-1);
			mesh_set_triangle(mesh, last_idx, new_idx+step_div_h-1, last_idx+step_div_h-1);
		} else {
			mesh_set_triangle(mesh, 0, new_idx, new_idx+step_div_h-1);
		}
		last_idx = new_idx;
	}

	if (!ground_dome) {
		new_idx = mesh->v_count;
		vx.pos.x = vx.pos.z = 0;
		vx.pos.y = -FIX_ONE;
		vx.normal.x = vx.normal.z = 0;
		vx.normal.y = MESH_NORMAL_UNIT;
		mesh_set_vertex_vx(mesh, &vx);

		for (j=1; j < step_div_h; j++) {
			mesh_set_triangle(mesh, last_idx+j-1, last_idx+j, new_idx);
		}
		mesh_set_triangle(mesh, last_idx+step_div_h-1, last_idx, new_idx);
	}

	mesh->flags |= MESH_HAS_COLOR | MESH_NO_TEXTURE;
	mesh_update_bounds(mesh);
}