Beispiel #1
0
void RenderUntextured(unsigned int offset, unsigned char *data, vector3d obj_center)
{
	BSP_BlockHeader blkhdr;
	unsigned char *curpos = data + offset;
	blkhdr.Read((char *) curpos);

#if defined(__BSP_DEBUG_DRAWNORMS_)
	BSP_FlatPoly fpoly;
	fpoly.Read((char *) curpos + blkhdr.MySize(), blkhdr);

	// just rendering a point a line along the norm for now - just need center and normal
	glColor3f(0.5, 0.5, 1.0);
	vector3d point = POFTranslate(fpoly.center);
	vector3d norm = point+(POFTranslate(fpoly.normal)*5);

	glBegin(GL_POINTS);	
		glVertex3fv((float *)&point);
	glEnd();

	glBegin(GL_LINE_STRIP);	
		glVertex3fv((float *)&point);
		glVertex3fv((float *)&norm);
	glEnd();
	// tail recurse
	fpoly.Destroy();
#endif
	RenderBSP(offset + blkhdr.size, data, obj_center);
}
Beispiel #2
0
void MakeFlatPoly(BSP_FlatPoly &dst, pcs_polygon &src, std::unordered_map<vector3d, int> &norms, std::unordered_map<vector3d, int> &verts, BSP_DefPoints &dpnts)
{
	dst.head.id = 2;
	dst.normal = src.norm;
	dst.nverts = src.verts.size();
	dst.green = dst.blue = dst.pad = 0;
	dst.red = 0xFF;

	dst.verts.resize(dst.nverts);
	std::vector<vector3d> vertices;
	vertices.reserve(dst.nverts);

	for (unsigned int i = 0; i < (unsigned)dst.nverts; i++)
	{
		vertices.push_back(src.verts[i].point);
		dst.verts[i].vertnum = verts[src.verts[i].point];
		dst.verts[i].normnum = norms[src.verts[i].norm];
	}
	dst.center = src.centeroid;

	// recalculate these just for accracy
	dst.center = dst.MyCenter(vertices);
	dst.radius = dst.MyRadius(dst.center, vertices);


	// last thing
	dst.head.size = dst.MySize();
}
Beispiel #3
0
void TranslateFPoly(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;
	blkhdr.Read((char *) curpos);

	vector3d point, norm;
	pcs_polygon temp_poly;

	BSP_FlatPoly fpoly;
	fpoly.Read((char *) curpos + blkhdr.MySize(), blkhdr);

	
	temp_poly.norm = POFTranslate(fpoly.normal);
	temp_poly.texture_id = -1;
	temp_poly.verts.resize(fpoly.nverts);

	
	for (int i = 0; i < fpoly.nverts; i++)
	{
		temp_poly.verts[i].point = POFTranslate(points.vertex_data[fpoly.verts[i].vertnum].vertex);
		temp_poly.verts[i].norm = POFTranslate(points.normals[fpoly.verts[i].normnum]);

		temp_poly.verts[i].u = 0;
		temp_poly.verts[i].v = 0;

	}

	if (upolys >= polygons.size())
	{
		polygons.resize(polygons.size() * 2);
	}
	polygons[upolys] = temp_poly;
	upolys++;

	BSPTransPMF(offset + blkhdr.size, data, points, polygons, upolys); // continue traversal
}
Beispiel #4
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;
}
Beispiel #5
0
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;
}