예제 #1
0
void MakeDefPoints(BSP_DefPoints& dpnts, std::vector<bsp_vert> &pntslist)
{
	dpnts.head.id = 1;
	dpnts.n_verts = pntslist.size();
	dpnts.n_norms = 0;
	dpnts.offset = 20 + pntslist.size();
	
	dpnts.norm_counts.resize(pntslist.size());
	dpnts.vertex_data.resize(pntslist.size());

	for (unsigned int i = 0; i < pntslist.size(); i++)
	{
		dpnts.norm_counts[i] = (unsigned char)pntslist[i].norms.size();
		dpnts.vertex_data[i].vertex = pntslist[i].point;

		dpnts.vertex_data[i].norms.resize(pntslist[i].norms.size());
		dpnts.n_norms += pntslist[i].norms.size();
		for (unsigned int j = 0; j < pntslist[i].norms.size(); j++)
		{
			dpnts.vertex_data[i].norms[j] = pntslist[i].norms[j];
		}
	}

	// last thing
	dpnts.head.size = dpnts.MySize();
}
예제 #2
0
void BSPTransPMF(unsigned int offset, unsigned char *data, 
		BSP_DefPoints &points, std::vector<pcs_polygon> &polygons,
		unsigned int &upolys)
{
	BSP_BlockHeader blkhdr;
	unsigned char *curpos = data + offset;
	//BSP_BoundBox *bbox;

	blkhdr.Read((char *) curpos);

	switch (blkhdr.id)
	{
		case 0: // End of Tree
			break;

		case 1: // DEFPOINTS
			points.Read((char *) curpos + blkhdr.MySize(), blkhdr); // interpret block
			BSPTransPMF(offset + blkhdr.size, data, points, polygons, upolys); // continue traversal
			break;

		case 2: // Untextured Poly
			TranslateFPoly(offset, data, points, polygons, upolys); // interpret and continue
			break;

		case 3: // Textured Poly
			TranslateTPoly(offset, data, points, polygons, upolys); // interpret and continue
			break;

		case 4: // Sortnorm
			InterpretSortNorm(offset, data, points, polygons, upolys); // interpret and continue
			break;
			
		case 5: //boundbox
			BSPTransPMF(offset + blkhdr.size, data, points, polygons, upolys); // continue traversal
			break;
		default:
			break;
	}

}
예제 #3
0
파일: BSPHandler.cpp 프로젝트: asarium/PCS2
std::string BSP::DataIn(char *buffer, int size)
{
	std::string stats;
	char *localptr = buffer;
	char cstemp[64];
	bool go = true;
	BSP_BoundBox	bnd;
	BSP_DefPoints	pnt;
	BSP_FlatPoly	fpol;
	BSP_SortNorm	snrm;
	BSP_TmapPoly	tpol;

	BSP_BlockHeader head;

	stats = "";
	//0 - EOF, 1 - DEFPOINTS, 2 - FLATPOLY, 3 - IMAPPOLY, 4- SHORNORM, 5- BOUNDBOX
	while (go)
	{


		head.Read(localptr);
		localptr += 8;


		if (localptr - buffer >= size)
		{
			go = false;
			break;
		}
		switch (head.id)
		{
			case 0:
				//stats += "EOF\n";
				//stats += "\n";
				//go = false;
				break;

			case 1:

				memset(cstemp, 0, 64);
				sprintf(cstemp, "[%d bytes (%d bytes unused)]", head.size, head.size - pnt.Read(localptr, head));
				localptr += (head.size - 8);//8 for the already added header

				//stats += "DEFPOINTS ";
				//stats += cstemp;
				//stats += "\n";

				/*
				memset(cstemp, 0, 64);
				sprintf(cstemp, "%d", pnt.n_norms);
				stats += "     +n_norms: ";
				stats += cstemp;
				stats += "\n";

				memset(cstemp, 0, 64);
				sprintf(cstemp, "%d", pnt.n_verts);
				stats += "     +n_verts: ";
				stats += cstemp;
				stats += "\n";

				memset(cstemp, 0, 64);
				sprintf(cstemp, "%d", pnt.offset);
				stats += "     +offset: +";
				stats += cstemp;
				stats += "\n";

				Collector = 0;
				for (i = 0; i < pnt.n_verts; i++)
				{
					if (i < pnt.n_norms)
						Collector += int(unsigned char(pnt.norm_counts[i]));
				}

				memset(cstemp, 0, 64);
				sprintf(cstemp, "%d bytes", sizeof(vector) * (Collector + pnt.n_verts));
				stats += "     +vertex data size: ";
				stats += cstemp;
				stats += "\n";*/
				//stats += "\n";

				Add_DefPoints(pnt);
				break;

			case 2:
				//stats += "FLATPOLY  ";

				memset(cstemp, 0, 64);
				sprintf(cstemp, "[%d bytes (%d bytes unused)]", head.size, head.size - fpol.Read(localptr, head));
				localptr += (head.size - 8);//8 for the already added header

				/*memset(cstemp, 0, 64);
				sprintf(cstemp, "   @+ Red: %d, Green: %d, Blue: %d, Pad: %d", fpol.red, fpol.green, fpol.blue, fpol.pad);
				stats += cstemp;
				stats += "\n";

				memset(cstemp, 0, 64);
				sprintf(cstemp, "   @+ Normal: (%f, %f, %f), Radius %f", fpol.normal.x, fpol.normal.y, fpol.normal.z, fpol.radius);
				stats += cstemp;
				stats += "\n";

				for (i = 0; i < fpol.nverts; i++)
				{

					memset(cstemp, 0, 64);
					sprintf(cstemp, "   @+ Point: (%f, %f, %f),",
							points[0].vertex_data[fpol.verts[i].vertnum].vertex.x,
							points[0].vertex_data[fpol.verts[i].vertnum].vertex.y,
							points[0].vertex_data[fpol.verts[i].vertnum].vertex.z);
					stats += cstemp;

					memset(cstemp, 0, 64);
					sprintf(cstemp, "  Normal: (%f, %f, %f),",
							points[0].vertex_data[fpol.verts[i].vertnum].norms[fpol.verts[i].normnum].x,
							points[0].vertex_data[fpol.verts[i].vertnum].norms[fpol.verts[i].normnum].y,
							points[0].vertex_data[fpol.verts[i].vertnum].norms[fpol.verts[i].normnum].z);
					stats += cstemp;

					stats += "\n";


				}*/

				//stats += "\n";

				Add_FlatPoly(fpol);
				break;

			case 3:
			//	stats += "IMAPPOLY ";

				memset(cstemp, 0, 64);
				sprintf(cstemp, "[%d bytes (%d bytes unused)]", head.size, head.size - tpol.Read(localptr, head));
				localptr += (head.size - 8);//8 for the already added header
				//stats += cstemp;
				//stats += "\n";



				/*memset(cstemp, 0, 64);
				sprintf(cstemp, "   @+ Normal: (%f, %f, %f), Radius %f", tpol.normal.x, tpol.normal.y, tpol.normal.z, tpol.radius);
				stats += cstemp;
				stats += "\n";

				for (i = 0; i < tpol.nverts; i++)
				{

					memset(cstemp, 0, 64);
					sprintf(cstemp, "   @+ Point: (%f, %f, %f),",
							points[0].vertex_data[tpol.verts[i].vertnum].vertex.x,
							points[0].vertex_data[tpol.verts[i].vertnum].vertex.y,
							points[0].vertex_data[tpol.verts[i].vertnum].vertex.z);
					stats += cstemp;

					memset(cstemp, 0, 64);
					sprintf(cstemp, "  Normal: (%f, %f, %f),",
							points[0].vertex_data[tpol.verts[i].vertnum].norms[tpol.verts[i].normnum].x,
							points[0].vertex_data[tpol.verts[i].vertnum].norms[tpol.verts[i].normnum].y,
							points[0].vertex_data[tpol.verts[i].vertnum].norms[tpol.verts[i].normnum].z);
					stats += cstemp;

					stats += "\n";


				}*/

				//stats += "\n";

				Add_TmapPoly(tpol);
				break;

			case 4:
				stats += "SORTNORM ";


				memset(cstemp, 0, 64);
				sprintf(cstemp, "[%d bytes (%d bytes unused)] ", head.size, head.size - snrm.Read(localptr, head));
				localptr += (head.size - 8);//8 for the already added header
				//stats += cstemp;
				//stats += "\n";

				/*memset(cstemp, 0, 64);
				sprintf(cstemp, "   @+ BackOffset: %d, FrontOffset: %d, OnlineOffset: %d, ",
						snrm.back_offset, snrm.front_offset, snrm.online_offset);
				stats += cstemp;
				stats += "\n";

				memset(cstemp, 0, 64);
				sprintf(cstemp, "   @+ PostListOffset: %d, PreListOffset: %d, ",
						snrm.back_offset, snrm.front_offset, snrm.online_offset);
				stats += cstemp;
				stats += "\n";

				memset(cstemp, 0, 64);
				sprintf(cstemp, "   @+ Plane_Normal: (%f, %f, %f)",
						snrm.plane_normal.x, snrm.plane_normal.y, snrm.plane_normal.z);
				stats += cstemp;
				stats += "\n";

				memset(cstemp, 0, 64);
				sprintf(cstemp, "   @+ Plane_Point: (%f, %f, %f)",
						snrm.plane_point.x, snrm.plane_point.y, snrm.plane_point.z);
				stats += cstemp;
				stats += "\n";

				memset(cstemp, 0, 64);
				sprintf(cstemp, "   @+ BoundBoxMin: (%f, %f, %f)",
						snrm.min_bounding_box_point.x, snrm.min_bounding_box_point.y, snrm.min_bounding_box_point.z);
				stats += cstemp;
				stats += "\n";

				memset(cstemp, 0, 64);
				sprintf(cstemp, "   @+ BoundBoxMax: (%f, %f, %f)",
						snrm.max_bounding_box_point.x, snrm.max_bounding_box_point.y, snrm.max_bounding_box_point.z);
				stats += cstemp;
				stats += "\n";
				stats += "\n";*/

				Add_SortNorm(snrm);
				break;

			case 5:
				//stats += "BOUNDBOX ";

				memset(cstemp, 0, 64);
				sprintf(cstemp, "[%d bytes (%d bytes unused)]", head.size, head.size - bnd.Read(localptr, head));
				localptr += (head.size - 8);//8 for the already added header
				/*stats += cstemp;
				stats += "\n";

				memset(cstemp, 0, 64);
				sprintf(cstemp, "   @+ BoundBoxMin: (%f, %f, %f)", bnd.min_point.x, bnd.min_point.y, bnd.min_point.z);
				stats += cstemp;
				stats += "\n";

				memset(cstemp, 0, 64);
				sprintf(cstemp, "   @+ BoundBoxMax: (%f, %f, %f)", bnd.max_point.x, bnd.max_point.y, bnd.max_point.z);
				stats += cstemp;
				stats += "\n";
				stats += "\n";*/


				Add_BoundBox(bnd);
				break;

			default:
				stats += "WARNING: Encountered UNKNOWN: Check data format and/or pointer alignment!\n";
				go = false;
				break;

		}
	}

	return stats;
}
예제 #4
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;
}