Exemple #1
0
int CalculateTreeSize(bsp_tree_node* root, std::vector<pcs_polygon> &polygons)
{
	if (root == NULL)
		return 8; // size of an BSP::EOF

	int ret_size = 0;
	switch(root->Type)
	{
		case POLY:
			// Size is BBOX (32 bytes) + Poly (variable on type and count) + EOF ( 8 bytes)
			ret_size += 32;
			for(unsigned int i = 0; i<root->poly_num.size(); i++){
				if (polygons[root->poly_num[i]].texture_id == -1)
					ret_size += 44 + 4 * polygons[root->poly_num[i]].verts.size();// Fplatpoly
				else 
					ret_size += 44 + 12 * polygons[root->poly_num[i]].verts.size();//Tmappoly
			}
			ret_size += 8;
			root->counted = true;
			return ret_size;

		default: //SPLIT
			root->counted = true;
			return 104 + CalculateTreeSize(root->front.get(), polygons) + CalculateTreeSize(root->back.get(), polygons); // 80 + 3*8 bytes for pre/post/onlist EOFs
	}
	return 0;

}
Exemple #2
0
double ZopfliCalculateBlockSize(const ZopfliLZ77Store* lz77,
                                size_t lstart, size_t lend, int btype) {
  unsigned ll_lengths[ZOPFLI_NUM_LL];
  unsigned d_lengths[ZOPFLI_NUM_D];

  double result = 3; /* bfinal and btype bits */

  if (btype == 0) {
    size_t length = ZopfliLZ77GetByteRange(lz77, lstart, lend);
    size_t rem = length % 65535;
    size_t blocks = length / 65535 + (rem ? 1 : 0);
    /* An uncompressed block must actually be split into multiple blocks if it's
       larger than 65535 bytes long. Eeach block header is 5 bytes: 3 bits,
       padding, LEN and NLEN (potential less padding for first one ignored). */
    return blocks * 5 * 8 + length * 8;
  } if (btype == 1) {
    GetFixedTree(ll_lengths, d_lengths);
  } else {
    GetDynamicLengths(lz77, lstart, lend, ll_lengths, d_lengths);
    result += CalculateTreeSize(ll_lengths, d_lengths);
  }

  result += CalculateBlockSymbolSize(
      ll_lengths, d_lengths, lz77, lstart, lend);

  return result;
}
Exemple #3
0
double ZopfliCalculateBlockSize(const unsigned short* litlens,
                                const unsigned short* dists,
                                size_t lstart, size_t lend, int btype) {
  size_t ll_counts[288];
  size_t d_counts[32];

  unsigned ll_lengths[288];
  unsigned d_lengths[32];

  double result = 3; /*bfinal and btype bits*/

  assert(btype == 1 || btype == 2); /* This is not for uncompressed blocks. */

  if(btype == 1) {
    GetFixedTree(ll_lengths, d_lengths);
  } else {
    ZopfliLZ77Counts(litlens, dists, lstart, lend, ll_counts, d_counts);
    ZopfliCalculateBitLengths(ll_counts, 288, 15, ll_lengths);
    ZopfliCalculateBitLengths(d_counts, 32, 15, d_lengths);
    PatchDistanceCodesForBuggyDecoders(d_lengths);
    result += CalculateTreeSize(ll_lengths, d_lengths, ll_counts, d_counts);
  }

  result += CalculateBlockSymbolSize(
      ll_lengths, d_lengths, litlens, dists, lstart, lend);

  return result;
}
Exemple #4
0
/*
Tries out OptimizeHuffmanForRle for this block, if the result is smaller,
uses it, otherwise keeps the original. Returns size of encoded tree and data in
bits, not including the 3-bit block header.
*/
static double TryOptimizeHuffmanForRle(
    const ZopfliLZ77Store* lz77, size_t lstart, size_t lend,
    const size_t* ll_counts, const size_t* d_counts,
    unsigned* ll_lengths, unsigned* d_lengths) {
  size_t ll_counts2[ZOPFLI_NUM_LL];
  size_t d_counts2[ZOPFLI_NUM_D];
  unsigned ll_lengths2[ZOPFLI_NUM_LL];
  unsigned d_lengths2[ZOPFLI_NUM_D];
  double treesize;
  double datasize;
  double treesize2;
  double datasize2;

  treesize = CalculateTreeSize(ll_lengths, d_lengths);
  datasize = CalculateBlockSymbolSizeGivenCounts(ll_counts, d_counts,
      ll_lengths, d_lengths, lz77, lstart, lend);

  memcpy(ll_counts2, ll_counts, sizeof(ll_counts2));
  memcpy(d_counts2, d_counts, sizeof(d_counts2));
  OptimizeHuffmanForRle(ZOPFLI_NUM_LL, ll_counts2);
  OptimizeHuffmanForRle(ZOPFLI_NUM_D, d_counts2);
  ZopfliCalculateBitLengths(ll_counts2, ZOPFLI_NUM_LL, 15, ll_lengths2);
  ZopfliCalculateBitLengths(d_counts2, ZOPFLI_NUM_D, 15, d_lengths2);
  PatchDistanceCodesForBuggyDecoders(d_lengths2);

  treesize2 = CalculateTreeSize(ll_lengths2, d_lengths2);
  datasize2 = CalculateBlockSymbolSizeGivenCounts(ll_counts, d_counts,
      ll_lengths2, d_lengths2, lz77, lstart, lend);

  if (treesize2 + datasize2 < treesize + datasize) {
    memcpy(ll_lengths, ll_lengths2, sizeof(ll_lengths2));
    memcpy(d_lengths, d_lengths2, sizeof(d_lengths2));
    return treesize2 + datasize2;
  }
  return treesize + datasize;
}
double Population::CalculateParsimonyCoefficient() {
	double covariance = 0;
	double variance = 0;

	CalculateRawFitness();
	CalculateTreeSize();
	
	/*
	for (size_t i = 0; i < pop_.size(); ++i) {
		double cov = static_cast<double>((pop_[i].GetTreeSize() - avg_tree_));
		double var = cov * cov;
		cov *= (pop_[i].GetFitness() - avg_fitness_);
		covariance += (cov / pop_.size());
		variance += (var / pop_.size());
	}

	return covariance / variance;
	*/

	return 1.0f;
}
Exemple #6
0
double ZopfliCalculateBlockSize(const unsigned short* litlens,
                                const unsigned short* dists,
                                size_t lstart, size_t lend, int btype) {
  unsigned ll_lengths[288];
  unsigned d_lengths[32];

  double result = 3; /* bfinal and btype bits */

  assert(btype == 1 || btype == 2); /* This is not for uncompressed blocks. */

  if(btype == 1) {
    GetFixedTree(ll_lengths, d_lengths);
  } else {
    GetDynamicLengths(litlens, dists, lstart, lend, ll_lengths, d_lengths);
    result += CalculateTreeSize(ll_lengths, d_lengths);
  }

  result += CalculateBlockSymbolSize(
      ll_lengths, d_lengths, litlens, dists, lstart, lend);

  return result;
}
Exemple #7
0
int PackTreeInBSP(bsp_tree_node* root, int offset, char *buffer, std::vector<pcs_polygon> &polygons,
	std::unordered_map<vector3d, int> &norms, std::unordered_map<vector3d, int> &verts, BSP_DefPoints &dpnts, vector3d geo_center, int buffsize, int &error_flags)
{
	// ----------- error detection ---------------
	// abort if error detected
	if (error_flags != BSP_NOERRORS)
		return 0; 

	// we're going to write off the end of the buffer gauranteed (smallest element is EOF - 8 bytes
	if (offset >= buffsize-7)
	{
		error_flags |= BSP_PACK_PREOVERFLOW;
		return 0;
	}
	// either we're written this node already, or it didn't get counted in size calculation.. this is bad, skip
	if (root != NULL && root->used == true)
	{
		error_flags |= BSP_PACK_DOUBLEUSE;
		return 0;
	}

	if (root != NULL && root->counted == false)
	{
		error_flags |= BSP_PACK_UNCOUNTED;
		return 0;
	}

	// ----------- finish error detection ---------------
	int size = 0;
	BSP_BlockHeader EndOfFile;
	EndOfFile.id = 0;
	EndOfFile.size = 0;

	BSP_BoundBox Bounding;
	Bounding.head.id = 5;
	Bounding.head.size = Bounding.MySize();

	BSP_TmapPoly tpoly;
	BSP_FlatPoly fpoly;

	BSP_SortNorm snorm;	
	
	if (root == NULL)
	{
		EndOfFile.Write(buffer+offset);
		return 8;
	}
	switch(root->Type)
	{
		case POLY:
			// write BBOX
			Bounding.max_point = root->bound_max;
			Bounding.min_point = root->bound_min;
			Bounding.Write(buffer+offset+size);
			size += Bounding.MySize();

			if (offset+CalculateTreeSize(root, polygons) > buffsize)
			{
				error_flags |= BSP_PACK_PREPOLYOVERFLOW;
				return 0;
			}
			// Size is BBOX (32 bytes) + Poly (variable on type and count) + EOF ( 8 bytes)
			
			// write POLY
			for(unsigned int i = 0; i<root->poly_num.size(); i++){
				if (polygons[root->poly_num[i]].texture_id == -1)
				{
					MakeFlatPoly(fpoly, polygons[root->poly_num[i]], norms, verts, dpnts);

					fpoly.Write(buffer+offset+size);
					size += fpoly.MySize();
				}
				else 
				{
					MakeTmapPoly(tpoly, polygons[root->poly_num[i]], norms, verts, dpnts);

					tpoly.Write(buffer+offset+size);
					size += tpoly.MySize();
				}
			}
			// write EOF
			EndOfFile.Write(buffer+offset+size);
			size += EndOfFile.MySize();
			root->used = true;

			if (offset+size > buffsize)
			{
				error_flags |= BSP_PACK_POLYOVERFLOW;
			}
			return size;

		default: //SPLIT
			size = 80;
			memset((char*)&snorm, 0, sizeof(BSP_SortNorm));
			snorm.head.id = 4;
			snorm.head.size = snorm.MySize();
			snorm.plane_point = root->point;
			snorm.plane_normal = root->normal;
			snorm.max_bounding_box_point = root->bound_max;
			snorm.min_bounding_box_point = root->bound_min;

			if (offset+CalculateTreeSize(root, polygons) > buffsize)
			{
				error_flags |= BSP_PACK_PRESPLITOVERFLOW;
				return 0;
			}

			snorm.prelist_offset = size;
			size += PackTreeInBSP(NULL, offset+size, buffer, polygons, norms, verts, dpnts, geo_center, buffsize, error_flags);
				
			snorm.postlist_offset = size;
			size += PackTreeInBSP(NULL, offset + size, buffer, polygons, norms, verts, dpnts, geo_center, buffsize, error_flags);
				
			snorm.online_offset = size;
			size += PackTreeInBSP(NULL, offset + size, buffer, polygons, norms, verts, dpnts, geo_center, buffsize, error_flags);
			
			snorm.front_offset = size;
			size += PackTreeInBSP(root->front.get(), offset+size, buffer, polygons, norms, verts, dpnts, geo_center, buffsize, error_flags);

			snorm.back_offset = size;
			size += PackTreeInBSP(root->back.get(), offset+size, buffer, polygons, norms, verts, dpnts, geo_center, buffsize, error_flags);

			snorm.Write(buffer+offset);

			// write a trailing BSP::EOF to make ourselves safe

			//EndOfFile.Write(buffer+offset+size);
			//size += EndOfFile.MySize();
			
			root->used = true;
			if (offset+size > buffsize)
			{
				error_flags |= BSP_PACK_SPLITOVERFLOW;
			}
			return size;
	}
	return 0;
}
Exemple #8
0
bool PCS_Model::PMFObj_to_POFObj2(int src_num, OBJ2 &dst, bool &bsp_compiled, float& model_radius)
{

	pcs_sobj &src = subobjects[src_num];

	dst.submodel_parent = src.parent_sobj;
	dst.offset = POFTranslate(src.offset);
	dst.geometric_center = POFTranslate(src.geometric_center);
	dst.submodel_name = APStoString(src.name);
	dst.properties = APStoString(src.properties);

	switch (src.movement_type)
	{
		case ROTATE:
			dst.movement_type = 1;
			break;
		default:
			dst.movement_type = -1;
	}
	switch (src.movement_axis)
	{
		case MV_X:
			dst.movement_axis = 0;
			break;
		case MV_Z:
			dst.movement_axis = 1;
			break;
		case MV_Y:
			dst.movement_axis = 2;
			break;
		default:
			dst.movement_axis = -1;
	}

	dst.reserved = 0;



	if(!can_bsp_cache || bsp_cache[src_num].changed)
	{

		// convert them to POF axis
		std::vector<pcs_polygon> clean_list = src.polygons;
		for (size_t i = 0; i < clean_list.size(); i++)
		{
			clean_list[i].norm = POFTranslate(clean_list[i].norm);
			for (size_t j = 0; j < clean_list[i].verts.size(); j++)
			{
				clean_list[i].verts[j].point = POFTranslate(clean_list[i].verts[j].point);
				clean_list[i].verts[j].norm = POFTranslate(clean_list[i].verts[j].norm);
			}
			clean_list[i].centeroid = PolygonCenter(clean_list[i]);
		}

		// BSP Compilation!
		// assemble points list
		std::vector<bsp_vert> points_list;
		std::vector<vector3d> pnts;
		std::unordered_map<vector3d, int> point_to_index;
		std::unordered_map<vector3d, int> normal_to_index;
		for (size_t i = 0; i < pnts.size(); i++) {
			point_to_index.insert(std::make_pair(pnts[i], i));
		}
		bsp_vert temp;
		points_list.reserve(clean_list.size());
		for (size_t i = 0; i < clean_list.size(); i++)
		{
			for (size_t j = 0; j < clean_list[i].verts.size(); j++)
			{
				auto point = point_to_index.find(clean_list[i].verts[j].point);
				if (point == point_to_index.end()) {
					point_to_index.insert(std::make_pair(clean_list[i].verts[j].point, points_list.size()));
					points_list.emplace_back();
					points_list.back().point = clean_list[i].verts[j].point;
					pnts.push_back(points_list.back().point);
				}
				auto normal = normal_to_index.find(clean_list[i].verts[j].norm);
				if (normal == normal_to_index.end()) {
					points_list[normal_to_index.size() / 128].norms.push_back(clean_list[i].verts[j].norm);
					normal_to_index.insert(std::make_pair(clean_list[i].verts[j].norm, normal_to_index.size()));
				}
			}
		}



		// create our defpoints
		BSP_DefPoints points;
		MakeDefPoints(points, points_list);
		vector3d AvgNormal;

		// create tree
		std::unique_ptr<bsp_tree_node> root = MakeTree(clean_list, dst.bounding_box_max_point, dst.bounding_box_min_point);

		// allocate buffer and write the defpoints
		dst.bsp_data.resize(points.head.size + CalculateTreeSize(root.get(), clean_list));

		if (points.Write(&dst.bsp_data.front()) != points.head.size)
			return false; // calculation error

		//std::ofstream bsp_debug("c:\\bsp.txt");
		//DebugPrintTree(root, bsp_debug);

		// pack the tree
		int error_flags = 0;
		PackTreeInBSP(root.get(), points.head.size, &dst.bsp_data.front(), clean_list, normal_to_index, point_to_index, points, dst.geometric_center, dst.bsp_data.size(), error_flags);
		
		// we got errors!
		if (error_flags != BSP_NOERRORS)
			return false;

		// update the bsp_compiled to be true
		bsp_compiled = true;

		// update the BSP cache with the new result
		if (can_bsp_cache)
		{
			// clear the saved - stale cache
			bsp_cache[src_num].decache();
			bsp_cache[src_num].bsp_data = dst.bsp_data;
			bsp_cache[src_num].changed = false;
		}


	}
	else // Used cached copy!
	{
		dst.bsp_data = bsp_cache[src_num].bsp_data;
	}
	dst.radius = 0.0f;
	dst.bounding_box_max_point = vector3d(FLT_MIN, FLT_MIN, FLT_MIN);
	dst.bounding_box_min_point = vector3d(FLT_MAX, FLT_MAX, FLT_MAX);

	vector3d global_offset(OffsetFromParent(src_num));
	for(unsigned int i = 0; i<src.polygons.size(); i++){
		for(unsigned int j = 0; j<src.polygons[i].verts.size(); j++){
			ExpandBoundingBoxes(dst.bounding_box_max_point, dst.bounding_box_min_point,  src.polygons[i].verts[j].point);
			float norm = Magnitude(src.polygons[i].verts[j].point);
			if (norm > dst.radius) {
				dst.radius = norm;
			}
			float global_norm = Magnitude(src.polygons[i].verts[j].point + global_offset);
			if (global_norm > model_radius) {
				model_radius = global_norm;
			}

		}
	}
	if (dst.radius == 0.0f) {
		dst.bounding_box_max_point = vector3d();
		dst.bounding_box_min_point = vector3d();
	}
	if (src.radius_overridden) {
		dst.radius = src.radius_override;
	}
	if (src.bounding_box_min_point_overridden) {
		dst.bounding_box_min_point = src.bounding_box_min_point_override;
	}
	if (src.bounding_box_max_point_overridden) {
		dst.bounding_box_max_point = src.bounding_box_max_point_override;
	}
	POFTranslateBoundingBoxes(dst.bounding_box_min_point, dst.bounding_box_max_point);
	return true;
}