示例#1
0
void a2estatic::load_from_memory(unsigned int object_count_, unsigned int vertex_count_,
								 float3* vertices_, float2* tex_coords_,
								 unsigned int* index_count_, uint3** indices_) {
	filename = "<memory>";
	a2estatic::vertex_count = vertex_count_;
	a2estatic::vertices = vertices_;
	
	a2estatic::tex_coord_count = vertex_count_;
	a2estatic::tex_coords = tex_coords_;
	
	a2estatic::index_count = index_count_;
	a2estatic::indices = indices_;
	a2estatic::tex_indices = indices_;
	normals = new float3[vertex_count];
	binormals = new float3[vertex_count];
	tangents = new float3[vertex_count];
	
	a2estatic::object_count = object_count_;
	min_index = new unsigned int[object_count];
	max_index = new unsigned int[object_count];
	memset(min_index, 0xFF, sizeof(unsigned int)*object_count);
	memset(max_index, 0, sizeof(unsigned int)*object_count);
	for(unsigned int i = 0; i < object_count; i++) {
		if(index_count[i] == 0) {
			min_index[i] = 0;
			max_index[i] = 0;
		}
		for(unsigned int j = 0; j < index_count[i]; j++) {			
			// also get the max/highest and min/lowest index number
			if(tex_indices[i][j].x > max_index[i]) max_index[i] = tex_indices[i][j].x;
			if(tex_indices[i][j].y > max_index[i]) max_index[i] = tex_indices[i][j].y;
			if(tex_indices[i][j].z > max_index[i]) max_index[i] = tex_indices[i][j].z;
			if(tex_indices[i][j].x < min_index[i]) min_index[i] = tex_indices[i][j].x;
			if(tex_indices[i][j].y < min_index[i]) min_index[i] = tex_indices[i][j].y;
			if(tex_indices[i][j].z < min_index[i]) min_index[i] = tex_indices[i][j].z;
		}
	}
	
	delete_sub_bboxes();
	sub_bboxes.resize(object_count);
	
	object_names.clear();
	object_names.resize(object_count);
	for(unsigned int i = 0; i < object_count; i++) {
		object_names[i] = "object #" + to_string(i);
	}
	
	// set this stuff for normal generating
	model_indices = indices;
	model_index_count = index_count;
	
	generate_normals();
	
	// set the actual model data after everything is computed correctly and its final state
	model_indices = indices;
	model_index_count = index_count;
	
	model_vertices = new float3*[object_count];
	model_vertex_count = new unsigned int[object_count];
	for(unsigned int i = 0; i < object_count; i++) {
		model_vertices[i] = &vertices[min_index[i]];
		model_vertex_count[i] = (min_index[i] != 0xFFFFFFFF ? max_index[i] - min_index[i] + 1 : 0);
	}
	
	build_bounding_box();
	
	// vertices vbo
	glGenBuffers(1, &vbo_vertices_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), vertices, GL_STATIC_DRAW);
	
	// tex_coords vbo
	glGenBuffers(1, &vbo_tex_coords_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_coords_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 2 * sizeof(float), tex_coords, GL_STATIC_DRAW);
	
	// normals/binormals/tangents vbo
	glGenBuffers(1, &vbo_normals_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_normals_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), normals, GL_STATIC_DRAW);
	
	glGenBuffers(1, &vbo_binormals_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_binormals_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), binormals, GL_STATIC_DRAW);
	
	glGenBuffers(1, &vbo_tangents_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_tangents_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), tangents, GL_STATIC_DRAW);
	
	// indices vbos
	vbo_indices_ids = new GLuint[object_count];
	for(unsigned int i = 0; i < object_count; i++) {
		glGenBuffers(1, &vbo_indices_ids[i]);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_indices_ids[i]);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_count[i] * 3 * sizeof(unsigned int), indices[i], GL_STATIC_DRAW);
	}
	
	// reset buffer
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	
	// general model setup
	model_setup();
}
int unpack(FILE* out,FILE* in) 
{
	freq cf;
	rangecoder rc;
	struct buffer buffer;
	struct ari_model model;
	size_t processed=0;

	buffer.offset = 0;
	buffer.len_power = 1+BLOCKSIZE_POWER;
	buffer.len = 1<<buffer.len_power;
	buffer.len_mask = buffer.len - 1;
	buffer.data = malloc(buffer.len);
	rc.in = in;
	model_setup(&model);

	if(!buffer.data)
		return -2;

	if (start_decoding(&rc) != 0) {   
		return -1;
	}

	while ( (cf = decode_culfreq(&rc,2)) ) {   
		freq i, blocksize;

		decode_update(&rc,1,1,2);

		blocksize = decode_short(&rc) | ((size_t)decode_short(&rc)) <<16;

		for (i=0; i<blocksize; i++) {   
			freq symbol;

			cf = decode_culfreq(&rc,model.counts[SYMBOLS]);

			symbol =  model_get_symbol(&model, cf);
			decode_update(&rc, model.counts[symbol+1]-model.counts[symbol],model.counts[symbol],model.counts[SYMBOLS]);
			model_update_freq(&model,symbol);

			/*fprintf(stderr,"Decoding:%d(%c),%ld,%ld\n",symbol,symbol,counts[symbol+1]-counts[symbol],counts[symbol]);*/

			if(symbol > 0xff) {
				const uint8_t extra_bits = code_to_length[symbol-0x100].extra_bits;
				const size_t  extra_data = decode_culshift(&rc, extra_bits);

				const size_t  length = code_to_length[symbol-0x100].start + extra_data;
				size_t distance;
				size_t distance_hi;

				decode_update_shift(&rc, 1, extra_data, extra_bits);

				distance = decode_culshift(&rc,8);
				decode_update_shift(&rc, 1, distance, 8);

				distance_hi = decode_culshift(&rc,8);
				decode_update_shift(&rc, 1, distance_hi, 8);

				distance |= distance_hi<<8;

				/* fprintf(stderr,"Retrieved length,distance:%ld,%ld\n",length,distance);*/
				buffer.offset = copy_back_bytes(&buffer,buffer.offset,distance,length);
			}
			else {
				buffer.data[buffer.offset++] = symbol;
				if(buffer.offset >= buffer.len) {
					buffer.offset = 0;
					fwrite(buffer.data,1,buffer.len,out);
				}
			}
		}
		processed += blocksize;
		if(processed > 1<<19) {
			done_decoding(&rc);
			start_decoding(&rc);
			processed=0;
		}
		/*fprintf(stderr,"%ld;;%d\n",blocksize,model.counts[SYMBOLS]);*/
       	}
	fwrite(buffer.data,1,buffer.offset,out);
	done_decoding(&rc);
	model_done(&model);
	free(buffer.data);

	fclose(out);
	return 0;
}
示例#3
0
/*! loads a .a2m model file
 *  @param filename the name of the .a2m model file
 *  @param vbo flag that specifies if vertex buffer objects should be used
 */
void a2estatic::load_model(const string& filename_) {
	file_io file(filename_, file_io::OPEN_TYPE::READ_BINARY);
	if(!file.is_open()) {
		return;
	}
	filename = filename_;

	// get type and name
	char* file_type = new char[9];
	file.get_block(file_type, 8);
	file_type[8] = 0;

	if(strcmp(file_type, "A2EMODEL") != 0) {
		log_error("non supported file type for %s: %s!", filename, file_type);
		delete [] file_type;
		file.close();
		return;
	}
	delete [] file_type;
	
	// get model version
	unsigned int version = file.get_uint();
	if(version != A2M_VERSION) {
		log_error("wrong model file version %u - should be %u!", version, A2M_VERSION);
		file.close();
		return;
	}

	// get model type and abort if it's not 0x00 or 0x02
	auto mtype = file.get_char();
	if(mtype != 0x00 && mtype != 0x02) {
		log_error("non supported model type: %u!", (unsigned int)(mtype & 0xFF));
		file.close();
		return;
	}

	if(mtype == 0x02) collision_model = true;

	vertex_count = file.get_uint();
	tex_coord_count = file.get_uint();
	vertices = new float3[vertex_count];
	normals = new float3[vertex_count];
	binormals = new float3[vertex_count];
	tangents = new float3[vertex_count];
	tex_coords = new float2[tex_coord_count];

	for(unsigned int i = 0; i < vertex_count; i++) {
		vertices[i].x = file.get_float();
		vertices[i].y = file.get_float();
		vertices[i].z = file.get_float();
	}
	for(unsigned int i = 0; i < tex_coord_count; i++) {
		tex_coords[i].x = file.get_float();
		tex_coords[i].y = 1.0f - file.get_float();
	}

	object_count = file.get_uint();
	delete_sub_bboxes();
	sub_bboxes.resize(object_count);

	object_names.clear();
	object_names.resize(object_count);
	for(unsigned int i = 0; i < object_count; i++) {
		file.get_terminated_block(object_names[i], 0xFF);
	}

	indices = new uint3*[object_count];
	tex_indices = new uint3*[object_count];
	index_count = new unsigned int[object_count];
	min_index = new unsigned int[object_count];
	max_index = new unsigned int[object_count];
	memset(min_index, 0xFF, sizeof(unsigned int)*object_count);
	memset(max_index, 0, sizeof(unsigned int)*object_count);
	for(unsigned int i = 0; i < object_count; i++) {
		index_count[i] = file.get_uint();
		indices[i] = new uint3[index_count[i]];
		tex_indices[i] = new uint3[index_count[i]];
		for(unsigned int j = 0; j < index_count[i]; j++) {
			indices[i][j].x = file.get_uint();
			indices[i][j].y = file.get_uint();
			indices[i][j].z = file.get_uint();
		}
		for(unsigned int j = 0; j < index_count[i]; j++) {
			tex_indices[i][j].x = file.get_uint();
			tex_indices[i][j].y = file.get_uint();
			tex_indices[i][j].z = file.get_uint();
		}
	}

	if(collision_model) {
		col_vertex_count = file.get_uint();
		col_vertices = new float3[col_vertex_count];
		for(unsigned int i = 0; i < col_vertex_count; i++) {
			col_vertices[i].x = file.get_float();
			col_vertices[i].y = file.get_float();
			col_vertices[i].z = file.get_float();
		}

		col_index_count = file.get_uint();
		col_indices = new uint3[col_index_count];
		for(unsigned int i = 0; i < col_index_count; i++) {
			col_indices[i].x = file.get_uint();
			col_indices[i].y = file.get_uint();
			col_indices[i].z = file.get_uint();
		}
	}

	file.close();
	
	// set this stuff for normal generating
	model_indices = indices;
	model_index_count = index_count;

	generate_normals();
	reorganize_model_data();
	
	// set the actual model data after everything is computed correctly and its final state
	model_indices = indices;
	model_index_count = index_count;
	
	model_vertices = new float3*[object_count];
	model_tex_coords = new float2*[object_count];
	model_vertex_count = new unsigned int[object_count];
	for(unsigned int i = 0; i < object_count; i++) {
		model_vertices[i] = &vertices[min_index[i]];
		model_tex_coords[i] = &tex_coords[min_index[i]];
		model_vertex_count[i] = max_index[i] - min_index[i] + 1;
	}

	build_bounding_box();
	
	// vertices vbo
	glGenBuffers(1, &vbo_vertices_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), vertices, GL_STATIC_DRAW);
	
	// tex_coords vbo
	glGenBuffers(1, &vbo_tex_coords_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_coords_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 2 * sizeof(float), tex_coords, GL_STATIC_DRAW);
	
	// normals/binormals/tangents vbo
	glGenBuffers(1, &vbo_normals_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_normals_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), normals, GL_STATIC_DRAW);
	
	glGenBuffers(1, &vbo_binormals_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_binormals_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), binormals, GL_STATIC_DRAW);
	
	glGenBuffers(1, &vbo_tangents_id);
	glBindBuffer(GL_ARRAY_BUFFER, vbo_tangents_id);
	glBufferData(GL_ARRAY_BUFFER, vertex_count * 3 * sizeof(float), tangents, GL_STATIC_DRAW);
	
	// indices vbos
	vbo_indices_ids = new GLuint[object_count];
	for(unsigned int i = 0; i < object_count; i++) {
		glGenBuffers(1, &vbo_indices_ids[i]);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_indices_ids[i]);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_count[i] * 3 * sizeof(unsigned int), indices[i], GL_STATIC_DRAW);
	}
	
	// reset buffer
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	
	// general model setup
	model_setup();
}