Exemplo n.º 1
0
void get_old_world_x_y (short *scene_x, short *scene_y)
{
	AABBOX box;
	float t, x, y, z, t1, t2, tx, ty, dx, dy, h, len;
	int i, j, h_max, h_min, h1, h2, h3, h4, sx, sy, zx, zy, i_min, i_max, j_min, j_max;

	x = click_line.center[X];
	y = click_line.center[Y];
	z = click_line.center[Z];
	dx = click_line.direction[X];
	dy = click_line.direction[Y];
	t = min2f(4.0f, max2f(-2.2f, z));
	if (t != z)
	{
		t = (t-z)/click_line.direction[Z];
		x += t*dx;
		y += t*dy;
	}
	t = 6.2f / click_line.direction[Z];
	len = min2f(max2f(t, -t), click_line.length);

	len = click_line.length;
	if (max2f(dx, -dx) < 0.000001f)
	{
		zx = 1;
		sx = 0;
	}
	else
	{
		zx = 0;
		if (dx < 0.0f) sx = -1;
		else sx = 1;
	}
	if (max2f(dy, -dy) < 0.000001f)
	{
		zy = 1;
		sy = 0;
	}
	else
	{
		zy = 0;
		if (dy < 0.0f) sy = -1;
		else sy = 1;
	}
	i = x*2.0f;
	j = y*2.0f;
	
	i_min = min2f(x, x+dx*len)*2.0f;
	i_max = max2f(x, x+dx*len)*2.0f;
	j_min = min2f(y, y+dy*len)*2.0f;
	j_max = max2f(y, y+dy*len)*2.0f;
	
	i_min = max2i(min2i(i_min, tile_map_size_x*6), 0);
	i_max = max2i(min2i(i_max, tile_map_size_x*6-1), 0);
	j_min = max2i(min2i(j_min, tile_map_size_y*6), 0);
	j_max = max2i(min2i(j_max, tile_map_size_y*6-1), 0);

	i = min2i(max2i(i, i_min), i_max-1);
	j = min2i(max2i(j, j_min), j_max-1);
	
	h = 0.0f;
	while ((i >= i_min) && (j >= j_min) && (i < i_max) && (j < j_max))
	{
		h1 = height_map[j*tile_map_size_x*6+i];
		h2 = height_map[j*tile_map_size_x*6+i+1];
		h3 = height_map[(j+1)*tile_map_size_x*6+i];
		h4 = height_map[(j+1)*tile_map_size_x*6+i+1];
		h_max = max2i(max2i(h1, h2), max2i(h3, h4));
		h_min = min2i(min2i(h1, h2), min2i(h3, h4));
		tx = i*0.5f;
		ty = j*0.5f;
		box.bbmin[X] = tx;
		box.bbmin[Y] = ty;
		box.bbmin[Z] = h_min*0.2f-2.2f;
		box.bbmax[X] = tx+1.0f;
		box.bbmax[Y] = ty+1.0f;
		box.bbmax[Z] = h_max*0.2f-2.2f;
		if (click_line_bbox_intersection(box))
		{
			box.bbmin[X] = tx+0.0f;
			box.bbmin[Y] = ty+0.0f;
			box.bbmin[Z] = h1*0.2f-2.2f;
			box.bbmax[X] = tx+0.5f;
			box.bbmax[Y] = ty+0.5f;
			box.bbmax[Z] = h1*0.2f-2.2f;
			if (click_line_bbox_intersection(box))
			{
				h = h1*0.2f-2.2f;
				break;
			}
			box.bbmin[X] = tx+0.5f;
			box.bbmin[Y] = ty+0.0f;
			box.bbmin[Z] = h2*0.2f-2.2f;
			box.bbmax[X] = tx+1.0f;
			box.bbmax[Y] = ty+0.5f;
			box.bbmax[Z] = h2*0.2f-2.2f;
			if (click_line_bbox_intersection(box))
			{
				h = h2*0.2f-2.2f;
				break;
			}
			box.bbmin[X] = tx+0.0f;
			box.bbmin[Y] = ty+0.5f;
			box.bbmin[Z] = h3*0.2f-2.2f;
			box.bbmax[X] = tx+0.5f;
			box.bbmax[Y] = ty+1.0f;
			box.bbmax[Z] = h3*0.2f-2.2f;
			if (click_line_bbox_intersection(box))
			{
				h = h3*0.2f-2.2f;
				break;
			}
			box.bbmin[X] = tx+0.5f;
			box.bbmin[Y] = ty+0.5f;
			box.bbmin[Z] = h4*0.2f-2.2f;
			box.bbmax[X] = tx+1.0f;
			box.bbmax[Y] = ty+1.0f;
			box.bbmax[Z] = h4*0.2f-2.2f;
			if (click_line_bbox_intersection(box))
			{
				h = h4*0.2f-2.2f;
				break;
			}
		}
		if ((zx == 1) && (zy == 1)) break;
		if (zx == 0) t1 = (tx+sx-x)/dx;
		else t1 = 10e30;
		if (zx == 0) t2 = (ty+sy-y)/dy;
		else t2 = -10e30;
		if (t1 < t2) i += 2*sx;
		else j += 2*sy;
		
		t = min2f(t1, t2);
		x += dx*t;
		y += dy*t;
	}
	t = (h-click_line.center[Z])/click_line.direction[Z];
	*scene_x = (click_line.center[X]+click_line.direction[X]*t) / 0.5;
	*scene_y = (click_line.center[Y]+click_line.direction[Y]*t) / 0.5;
}
Exemplo n.º 2
0
static __inline__ int check_shadow_lines_outside(const AABBOX bbox, const FRUSTUM frustum, const FRUSTUM_DATA data, const VECTOR3 light_dir, Uint32 mask, Uint32 point_mask)
{
	VECTOR3 _p;
	VECTOR4 p;
	float tmp, vmin, vmax, step, hit[16];
	int i, j, k, l, intersect;
	
	memset(hit, 0, sizeof(hit));
	
	for (i = 0, k = 1; k <= point_mask; i++, k += k)
	{
		if (k & point_mask)
		{
			get_point_from_aabbox(_p, bbox, i);
			VAssign4(p, _p, 1.0f);
			vmin = 0.0f;
			vmax = BOUND_HUGE;
			intersect = 1;

			for (j = 0, l = 1; l <= mask; j++, l += l)
			{
				if (l & mask)
				{
					tmp = VDot4(p, frustum[j].plane);
					
					if (data[j].zero == 0)
					{
						step = tmp/data[j].scale;
						if (step < 0.0f)
						{
							if (tmp < 0.0f)
							{
								intersect = 0;
							}
						}
						else
						{
							hit[j] = max2f(hit[j], step);
							if (intersect != 0)
							{
								if (data[j].mask)
								{
									vmin = max2f(vmin, step);
								}
								else
								{
									vmax = min2f(vmax, step);
								}
								if (vmin > vmax)
								{
									intersect = 0;
								}
							}
						}
					}
					else
					{
						if (tmp < 0.0f)
						{
							intersect = 0;
						}
					}
				}
			}
			if (intersect != 0) return INTERSECT;
		}
	}
	return check_shadow_line_walk_outside(bbox, frustum, light_dir, mask, hit);
}
Exemplo n.º 3
0
static e3d_object* do_load_e3d_detail(e3d_object* cur_object)
{
	e3d_header header;
	e3d_material material;
	char cur_dir[1024];
	int i, idx, l, mem_size, vertex_size, material_size;
	int file_pos, indices_size, index_size;
	char text_file_name[1024];
	Uint32 tmp;
	Uint16 tmp_16;
	Uint8* index_pointer;
	el_file_ptr file;
	version_number version;
	
	if (cur_object == 0) return 0;

	memset(cur_dir, 0, sizeof(cur_dir));
	//get the current directory
	l = strlen(cur_object->file_name);
	//parse the string backwards, until we find a /
	while (l > 0)
	{
		if ((cur_object->file_name[l] == '/') || (cur_object->file_name[l] == '\\')) break;
		l--;
	}

	i = 0;
	if (l)//prevent invalid dir names
	{
		while (l >= 0)
		{
			cur_dir[i] = cur_object->file_name[i];
			i++;
			l--;
		}
		cur_dir[i+1] = 0;
	}

	LOG_DEBUG_OLD("Loading e3d file '%s'.", cur_object->file_name);

	file = el_open(cur_object->file_name);
	if (file == 0)
	{
		LOG_ERROR_OLD("Can't open file '%s'!", cur_object->file_name);

		free_e3d_pointer(cur_object);

		return 0;
	}

	if (read_and_check_elc_header(file, EL3D_FILE_MAGIC_NUMBER, &version, cur_object->file_name) != 0)
	{
		LOG_ERROR_OLD("File '%s' has wrong header!", cur_object->file_name);

		free_e3d_pointer(cur_object);
		el_close(file);

		return 0;
	}
	
	el_read(file, sizeof(e3d_header), &header);

	cur_object->vertex_no = SDL_SwapLE32(header.vertex_no);
	cur_object->index_no = SDL_SwapLE32(header.index_no);
	cur_object->material_no = SDL_SwapLE32(header.material_no);
	vertex_size = SDL_SwapLE32(header.vertex_size);
	material_size = SDL_SwapLE32(header.material_size);
	index_size = SDL_SwapLE32(header.index_size);

	LOG_DEBUG_OLD("E3d file vertex count %d and size %d.",
		cur_object->vertex_no, vertex_size);

	LOG_DEBUG_OLD("E3d file index count %d and size %d.",
		cur_object->index_no, index_size);

	LOG_DEBUG_OLD("E3d file material count %d and size %d.",
		cur_object->material_no, material_size);

	LOG_DEBUG_OLD("E3d file version %d.%d.%d.%d.", version[0],
		version[1], version[2], version[3]);

	if ((version[0] == 1) && (version[1] == 1))
	{
		if ((header.vertex_options & 0xF0) != 0)
		{
			LOG_ERROR_OLD("Unknow options (%d) for file %s.",
				header.vertex_options, cur_object->file_name);
		}

		header.vertex_options &= 0x0F;

		if ((header.vertex_format & 0xE0) != 0)
		{
			LOG_ERROR_OLD("Unknow format (%d) for file %s.",
				header.vertex_format, cur_object->file_name);
		}

		header.vertex_format &= 0x1F;
	}
	else
	{
		if ((version[0] == 1) && (version[1] == 0))
		{
			header.vertex_format = 0;
			header.vertex_options ^= 0x01;
			header.vertex_options &= 0x07;
		}
		else
		{
			LOG_ERROR_OLD("File '%s' has wrong version number!",
				cur_object->file_name);

			free_e3d_pointer(cur_object);
			el_close(file);

			return 0;
		}
	}

	idx = 0;

	if (has_normal(header.vertex_options))
	{
		idx += 1;
	}

	if (has_color(header.vertex_options))
	{
		idx += 2;
	}

	cur_object->vertex_layout = &(vertex_layout_array[idx]);

	// They have at least the size we expected

	if (check_vertex_size(vertex_size, header.vertex_options, header.vertex_format) == 0)
	{
		LOG_ERROR_OLD("File '%s' has wrong vertex size!", cur_object->file_name);

		free_e3d_pointer(cur_object);
		el_close(file);

		return 0;
	}

	if (material_size != get_material_size(header.vertex_options))
	{
		LOG_ERROR_OLD("File '%s' has wrong material size! Expected size %d, found size %d.",
			cur_object->file_name, get_material_size(header.vertex_options), material_size);
		free_e3d_pointer(cur_object);
		el_close(file);
		return 0;
	}

	if (short_index(header.vertex_format))
	{
		if (index_size != sizeof(Uint16))
		{
			LOG_ERROR_OLD("File '%s' has wrong index size! Expected size %d, found size %d.",
				cur_object->file_name, sizeof(Uint16), index_size);
			free_e3d_pointer(cur_object);
			el_close(file);
			return 0;
		}
	}
	else
	{
		if (index_size != sizeof(Uint32))
		{
			LOG_ERROR_OLD("File '%s' has wrong index size! Expected size %d, found size %d.",
				cur_object->file_name, sizeof(Uint32), index_size);
			free_e3d_pointer(cur_object);
			el_close(file);
			return 0;
		}
	}

	LOG_DEBUG_OLD("Reading vertices at %d from e3d file '%s'.",
		SDL_SwapLE32(header.vertex_offset), cur_object->file_name);
	// Now reading the vertices
	el_seek(file, SDL_SwapLE32(header.vertex_offset), SEEK_SET);

	cur_object->vertex_data = malloc(cur_object->vertex_no * cur_object->vertex_layout->size);
	mem_size = cur_object->vertex_no * cur_object->vertex_layout->size;
	if (!CHECK_POINTER(cur_object->vertex_data, "vertex data")) return 0;

	read_vertex_buffer(file, (float*)(cur_object->vertex_data), cur_object->vertex_no,
		vertex_size, header.vertex_options, header.vertex_format);

	LOG_DEBUG_OLD("Reading indices at %d from e3d file '%s'.",
		SDL_SwapLE32(header.index_offset), cur_object->file_name);
	// Now reading the indices
	el_seek(file, SDL_SwapLE32(header.index_offset), SEEK_SET);

	if (cur_object->index_no < 65536)
	{
		indices_size = 2;
		cur_object->index_type = GL_UNSIGNED_SHORT;
	}
	else
	{
		indices_size = 4;
		cur_object->index_type = GL_UNSIGNED_INT;
	}

	cur_object->indices = malloc(cur_object->index_no * indices_size);

	index_pointer = 0;

	for (i = 0; i < cur_object->index_no; i++)
	{
		if (index_size == 2)
		{
			el_read(file, sizeof(Uint16), &tmp_16);
			tmp = SDL_SwapLE16(tmp_16);
		}
		else
		{
			el_read(file, sizeof(Uint32), &tmp);
			tmp = SDL_SwapLE32(tmp);
		}

		if (indices_size == 2)
		{
			((Uint16*)(cur_object->indices))[i] = tmp;
		}
		else
		{
			((Uint32*)(cur_object->indices))[i] = tmp;
		}
	}

	// only allocate the materials structure if it doesn't exist (on initial load)
	if (cur_object->materials == 0)
	{
		cur_object->materials = (e3d_draw_list*)malloc(cur_object->material_no*sizeof(e3d_draw_list));
		if (!CHECK_POINTER(cur_object->materials, "materials")) return 0;
		memset(cur_object->materials, 0, cur_object->material_no * sizeof(e3d_draw_list));
	}
	mem_size += cur_object->material_no * sizeof(e3d_draw_list);

	LOG_DEBUG_OLD("Reading materials at %d from e3d file '%s'.",
		SDL_SwapLE32(header.material_offset), cur_object->file_name);
	// Now reading the materials
	el_seek(file, SDL_SwapLE32(header.material_offset), SEEK_SET);
	
	cur_object->min_x = 1e10f;
	cur_object->min_y = 1e10f;
	cur_object->min_z = 1e10f;
	cur_object->max_x = -1e10f;
	cur_object->max_y = -1e10f;
	cur_object->max_z = -1e10f;
	cur_object->max_size = -1e10f;

	for (i = 0; i < cur_object->material_no; i++)
	{
		
		file_pos = el_tell(file);
		el_read(file, sizeof(e3d_material), &material);
		safe_snprintf(text_file_name, sizeof(text_file_name), "%s%s", cur_dir, material.material_name);

		cur_object->materials[i].options = SDL_SwapLE32(material.options);
#ifdef	MAP_EDITOR
#ifdef	NEW_TEXTURES
		cur_object->materials[i].texture = load_texture_cached(text_file_name, tt_mesh);
#else	/* NEW_TEXTURES */
		cur_object->materials[i].texture = load_texture_cache(text_file_name,0);
#endif	/* NEW_TEXTURES */
#else	//MAP_EDITOR
#ifdef	NEW_TEXTURES
		cur_object->materials[i].texture = load_texture_cached(text_file_name, tt_mesh);
#else	/* NEW_TEXTURES */
#ifdef	NEW_ALPHA
		// prepare to load the textures depending on if it is transparent or not (diff alpha handling)
		if (material_is_transparent(cur_object->materials[i].options))
		{	// is this object transparent?
			cur_object->materials[i].texture= load_texture_cache_deferred(text_file_name, -1);
		}
		else
		{
			cur_object->materials[i].texture= load_texture_cache_deferred(text_file_name, -1);	//255);
		}
#else	//NEW_ALPHA
//		cur_object->materials[i].texture = load_texture_cache_deferred(text_file_name, 255);
		cur_object->materials[i].texture = load_texture_cache_deferred(text_file_name, 0);
#endif	//NEW_ALPHA
#endif	/* NEW_TEXTURES */
#endif	//MAP_EDITOR

		cur_object->materials[i].min_x = SwapLEFloat(material.min_x);
		cur_object->materials[i].min_y = SwapLEFloat(material.min_y);
		cur_object->materials[i].min_z = SwapLEFloat(material.min_z);
		cur_object->materials[i].max_x = SwapLEFloat(material.max_x);
		cur_object->materials[i].max_y = SwapLEFloat(material.max_y);
		cur_object->materials[i].max_z = SwapLEFloat(material.max_z);
		// calculate the max size for cruse LOD processing
		cur_object->materials[i].max_size= max2f(max2f(cur_object->materials[i].max_x-cur_object->materials[i].min_x, cur_object->materials[i].max_y-cur_object->materials[i].min_y), cur_object->materials[i].max_z-cur_object->materials[i].min_z);

		cur_object->min_x = min2f(cur_object->min_x, cur_object->materials[i].min_x);
		cur_object->min_y = min2f(cur_object->min_y, cur_object->materials[i].min_y);
		cur_object->min_z = min2f(cur_object->min_z, cur_object->materials[i].min_z);
		cur_object->max_x = max2f(cur_object->max_x, cur_object->materials[i].max_x);
		cur_object->max_y = max2f(cur_object->max_y, cur_object->materials[i].max_y);
		cur_object->max_z = max2f(cur_object->max_z, cur_object->materials[i].max_z);
		cur_object->max_size = max2f(cur_object->max_size, cur_object->materials[i].max_size);

		cur_object->materials[i].triangles_indices_index = indices_size*SDL_SwapLE32(material.index) + index_pointer;
		cur_object->materials[i].triangles_indices_count = SDL_SwapLE32(material.count);
		cur_object->materials[i].triangles_indices_min = SDL_SwapLE32(material.triangles_min_index);
		cur_object->materials[i].triangles_indices_max = SDL_SwapLE32(material.triangles_max_index);

		file_pos += SDL_SwapLE32(material_size);

		el_seek(file, file_pos, SEEK_SET);

	}
	el_close(file);

	LOG_DEBUG_OLD("Building vertex buffers for e3d file '%s'.",
		cur_object->file_name);

	//Generate the buffers
	glGenBuffersARB(1, &cur_object->vertex_vbo);
	glBindBufferARB(GL_ARRAY_BUFFER_ARB,
		cur_object->vertex_vbo);
	glBufferDataARB(GL_ARRAY_BUFFER_ARB,
		cur_object->vertex_no * cur_object->vertex_layout->size,
		cur_object->vertex_data, GL_STATIC_DRAW_ARB);
#ifndef	MAP_EDITOR
	free(cur_object->vertex_data);
	cur_object->vertex_data = 0;
#endif	//MAP_EDITOR
		
	glGenBuffersARB(1, &cur_object->indices_vbo);
	glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
		cur_object->indices_vbo);
	glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
		cur_object->index_no * indices_size,
		cur_object->indices, GL_STATIC_DRAW_ARB);
#ifndef	MAP_EDITOR
	free(cur_object->indices);
	cur_object->indices = 0;
#endif	//MAP_EDITOR
				
	glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
	glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

#ifndef	MAP_EDITOR
	LOG_DEBUG_OLD("Adding e3d file '%s' to cache.",
		cur_object->file_name);

	cache_adj_size(cache_e3d, mem_size, cur_object);
#endif	//MAP_EDITOR
	return cur_object;
}