Exemple #1
0
void InterpretSortNorm(unsigned int offset, unsigned char *data, 
					   BSP_DefPoints &points, std::vector<pcs_polygon> &polygons,
						unsigned int &upolys)
{
	BSP_BlockHeader blkhdr;
	BSP_SortNorm snorm;
	unsigned char *curpos = data + offset;
	
	blkhdr.Read((char *) curpos);
	
	snorm.Read((char *) curpos + blkhdr.MySize(), blkhdr);

	if (snorm.front_offset)
		BSPTransPMF(offset + snorm.front_offset, data, points, polygons, upolys); // continue traversal

	if (snorm.back_offset)
		BSPTransPMF(offset + snorm.back_offset, data, points, polygons, upolys); // continue traversal

	if (snorm.prelist_offset)
		BSPTransPMF(offset + snorm.prelist_offset, data, points, polygons, upolys); // continue traversal
	
	if (snorm.postlist_offset)
		BSPTransPMF(offset + snorm.postlist_offset, data, points, polygons, upolys); // continue traversal

	if (snorm.online_offset)
		BSPTransPMF(offset + snorm.online_offset, data, points, polygons, upolys); // continue traversal


	
	// No tail recursion on sortnorms
}	
Exemple #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;
	}

}
Exemple #3
0
void TranslateTPoly(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;

	BSP_TmapPoly tpoly;
	pcs_polygon temp_poly;

	tpoly.Read((char *) curpos + blkhdr.MySize(), blkhdr);
	// 2^32-1 = 4294967295
	// 2^8-1 = 255

	temp_poly.norm = POFTranslate(tpoly.normal);
	temp_poly.texture_id = tpoly.tmap_num;
	temp_poly.verts.resize(tpoly.nverts);
	//norm = tpoly.normal

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

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

	}


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

	BSPTransPMF(offset + blkhdr.size, data, points, polygons, upolys); // continue traversal
}
Exemple #4
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
}
Exemple #5
0
int PCS_Model::LoadFromPOF(std::string filename, AsyncProgress* progress)
{
	this->Reset();
	char cstringtemp[256];
	progress->setMessage("Opening and Reading POF");
	progress->Notify();

	std::ifstream infile(filename.c_str(), std::ios::in | std::ios::binary);
	if (!infile)
		return 1;

	POF poffile(infile);
	progress->setTarget(4 + poffile.SPCL_Count() + poffile.GPNT_SlotCount() + poffile.MPNT_SlotCount() + poffile.TGUN_Count_Banks() + poffile.TMIS_Count_Banks() +
					poffile.DOCK_Count_Docks() + poffile.FUEL_Count_Thrusters() + poffile.INSG_Count_Insignia() + poffile.PATH_Count_Paths() + 
					poffile.GLOW_Count_LightGroups() + poffile.OBJ2_Count());

	// Update Progress
	progress->incrementWithMessage("Getting Header");

	header.max_radius = poffile.HDR2_Get_MaxRadius();
	header.max_radius_override = header.max_radius;
	header.min_bounding = poffile.HDR2_Get_MinBound();
	header.max_bounding = poffile.HDR2_Get_MaxBound();
	POFTranslateBoundingBoxes(header.min_bounding, header.max_bounding);
	header.min_bounding_override = header.min_bounding;
	header.max_bounding_override = header.max_bounding;

	unsigned int i, j, k;
	int scratch; // useless variable - for legacy remnant argument
	poffile.HDR2_Get_Details(scratch, header.detail_levels);
	poffile.HDR2_Get_Debris(scratch, header.debris_pieces);

	header.mass = poffile.HDR2_Get_Mass();
	header.mass_center = POFTranslate(poffile.HDR2_Get_MassCenter());
	poffile.HDR2_Get_MomentInertia(header.MOI);

	// --------- convert cross sections --------- 
	std::vector<cross_section> sections;
	poffile.HDR2_Get_CrossSections(scratch, sections);
	
	if (scratch != -1)
	{
		header.cross_sections.resize(scratch);

		for (i = 0; i < header.cross_sections.size(); i++)
		{
			header.cross_sections[i].depth = sections[i].depth;
			header.cross_sections[i].radius = sections[i].radius;
		}
	}
	// --------- ACEN --------- 
	// Update Progress
	progress->incrementWithMessage("Getting ACEN, TXTR, PINF, EYE");
	autocentering = POFTranslate(poffile.ACEN_Get_acen());

	// --------- TXTR --------- 
	textures.resize(poffile.TXTR_Count_Textures());
	std::string tmp_test;
	for (i = 0; i < textures.size(); i++)
	{
		tmp_test = poffile.TXTR_GetTextures(i);
		textures[i] = tmp_test;
	}

	// --------- ---------------------- ---------
	
	model_info = poffile.PINF_Get();

	can_bsp_cache = false;
	for (i = 0; i < model_info.size(); i++)
	{
		if ( //strstr(model_info[i].c_str(), "BSPGEN") || // Volition's Compiler - caching revoked 2008-02-11 by Kazan because cannot gaurantee that tagged models actually game from V's compiler
			//strstr(model_info[i].c_str(), "POF-CS Compiler v1.3.4") ||  // removed PCS1 from recognized cacheable list 2008-01-10 - Kazan
			strstr(model_info[i].c_str(), PCS2_COMP_VERSION.mb_str()))
		{
			can_bsp_cache = true;
			break;
		}
	}


	// ---------  EYE --------- 
	eyes.resize(poffile.EYE_Count_Eyes());

	for (i = 0; i < eyes.size(); i++)
	{
		poffile.EYE_Get_Eye(i, eyes[i].sobj_number, eyes[i].sobj_offset, eyes[i].normal);
		eyes[i].sobj_offset = POFTranslate(eyes[i].sobj_offset);
		eyes[i].normal = POFTranslate(eyes[i].normal);
	}

	// --------- SPCL --------- 
	special.resize(poffile.SPCL_Count());

	for (i = 0; i < special.size(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Getting Special %d", i);
		progress->incrementWithMessage(cstringtemp);
		poffile.SPCL_Get_Special(i, special[i].name, special[i].properties, 
									special[i].point, special[i].radius);
		special[i].point = POFTranslate(special[i].point);
	}


	// --------- weapons (GPNT/MPNT) --------- 
	weapons.resize(poffile.GPNT_SlotCount() + poffile.MPNT_SlotCount());

	for (i = 0; i < poffile.GPNT_SlotCount(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Getting Gun Point %d", i);
		progress->incrementWithMessage(cstringtemp);
		weapons[i].type = GUN;
		weapons[i].muzzles.resize(poffile.GPNT_PointCount(i));

		for (j = 0; j < poffile.GPNT_PointCount(i); j++)
		{
			poffile.GPNT_GetPoint(i, j, weapons[i].muzzles[j].point,
										weapons[i].muzzles[j].norm);
			weapons[i].muzzles[j].point = POFTranslate(weapons[i].muzzles[j].point);
			weapons[i].muzzles[j].norm = POFTranslate(weapons[i].muzzles[j].norm);
		}
	}

	k = poffile.GPNT_SlotCount();
	for (i = 0; i < poffile.MPNT_SlotCount(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Getting Missile Point %d", i);
		progress->incrementWithMessage(cstringtemp);
		weapons[i+k].type = MISSILE;
		weapons[i+k].muzzles.resize(poffile.MPNT_PointCount(i));

		for (j = 0; j < poffile.MPNT_PointCount(i); j++)
		{
			poffile.MPNT_GetPoint(i, j, weapons[i+k].muzzles[j].point,
										weapons[i+k].muzzles[j].norm);
			weapons[i+k].muzzles[j].point = POFTranslate(weapons[i+k].muzzles[j].point);
			weapons[i+k].muzzles[j].norm = POFTranslate(weapons[i+k].muzzles[j].norm);
		}
	}

	// --------- turrets TGUN/TMIS --------- 
	turrets.resize(poffile.TGUN_Count_Banks() + poffile.TMIS_Count_Banks());

	for (i = 0; i < poffile.TGUN_Count_Banks(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Getting Gun Turret %d", i);
		progress->incrementWithMessage(cstringtemp);
		turrets[i].type = GUN;
		poffile.TGUN_Get_Bank(i, turrets[i].sobj_parent, 
								 turrets[i].sobj_par_phys, 
								 turrets[i].turret_normal);

		turrets[i].turret_normal = POFTranslate(turrets[i].turret_normal);

		turrets[i].fire_points.resize(poffile.TGUN_Count_Points(i));

		for (j = 0; j < poffile.TGUN_Count_Points(i); j++)
		{
			poffile.TGUN_Get_FirePoint(i, j, turrets[i].fire_points[j]);
			turrets[i].fire_points[j] = POFTranslate(turrets[i].fire_points[j]);
		}
	}

	k = poffile.TGUN_Count_Banks();
	for (i = 0; i < poffile.TMIS_Count_Banks(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Getting Missile Turret %d", i);
		progress->incrementWithMessage(cstringtemp);
		turrets[i+k].type = GUN;
		poffile.TMIS_Get_Bank(i, turrets[i+k].sobj_parent, 
								 turrets[i+k].sobj_par_phys, 
								 turrets[i+k].turret_normal);

		turrets[i+k].turret_normal = POFTranslate(turrets[i+k].turret_normal);

		turrets[i+k].fire_points.resize(poffile.TMIS_Count_Points(i));

		for (j = 0; j < poffile.TMIS_Count_Points(i); j++)
		{
			poffile.TMIS_Get_FirePoint(i, j, turrets[i+k].fire_points[j]);
			turrets[i+k].fire_points[j] = POFTranslate(turrets[i+k].fire_points[j]);
		}
	}

	// --------- docking --------- 
	docking.resize(poffile.DOCK_Count_Docks());

	for (i = 0; i < poffile.DOCK_Count_Docks(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Getting Docking Point %d", i);
		progress->incrementWithMessage(cstringtemp);
		poffile.DOCK_Get_DockProps(i, docking[i].properties);
		
		docking[i].dockpoints.resize(poffile.DOCK_Count_Points(i));

		for (j = 0; j < poffile.DOCK_Count_Points(i); j++)
		{
			poffile.DOCK_Get_Point(i, j, docking[i].dockpoints[j].point, 
										 docking[i].dockpoints[j].norm);
			docking[i].dockpoints[j].point = POFTranslate(docking[i].dockpoints[j].point);
			docking[i].dockpoints[j].norm = POFTranslate(docking[i].dockpoints[j].norm);
			
		}

		docking[i].paths.resize(poffile.DOCK_Count_SplinePaths(i));

		for (j = 0; j < poffile.DOCK_Count_SplinePaths(i); j++)
		{
			poffile.DOCK_Get_SplinePath(i, j, docking[i].paths[j]);
		}
	}

	// --------- thrusters --------- 
	thrusters.resize(poffile.FUEL_Count_Thrusters());

	for (i = 0; i < poffile.FUEL_Count_Thrusters(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Getting Thruster %d", i);
		progress->incrementWithMessage(cstringtemp);
		poffile.FUEL_Get_ThrusterProps(i, thrusters[i].properties);

		thrusters[i].points.resize(poffile.FUEL_Count_Glows(i));
		for (j = 0; j < poffile.FUEL_Count_Glows(i); j++)
		{
			poffile.FUEL_Get_GlowPoint(i, j, thrusters[i].points[j].radius,
											 thrusters[i].points[j].pos,
											 thrusters[i].points[j].norm);
			thrusters[i].points[j].pos = POFTranslate(thrusters[i].points[j].pos);
			thrusters[i].points[j].norm = POFTranslate(thrusters[i].points[j].norm);
		}
	}

	// --------- shield_mesh --------- 
	// Update Progress
	progress->incrementWithMessage("Getting Shields");
	shield_mesh.resize(poffile.SHLD_Count_Faces());
	int fcs[3], nbs[3];
	for (i = 0; i < shield_mesh.size(); i++)
	{
		poffile.SHLD_Get_Face(i, shield_mesh[i].face_normal, fcs, nbs);

		shield_mesh[i].face_normal = POFTranslate(shield_mesh[i].face_normal);\

		for (j = 0; j < 3; j++)
		{
			poffile.SHLD_Get_Vertex(fcs[j], shield_mesh[i].corners[j]);
			shield_mesh[i].corners[j] = POFTranslate(shield_mesh[i].corners[j]);
		}
	}

	// --------- insignia --------- 
	insignia.resize(poffile.INSG_Count_Insignia());

	vector3d uv, vv;
	float *u = (float *)&uv, *v = (float *)&vv;

	for (i = 0; i < poffile.INSG_Count_Insignia(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Getting Insignia %d", i);
		progress->incrementWithMessage(cstringtemp);
		poffile.INSG_Get_Insignia(i, insignia[i].lod, insignia[i].offset);

		insignia[i].offset = POFTranslate(insignia[i].offset);

		insignia[i].faces.resize(poffile.INSG_Count_Faces(i));

		for (j = 0; j < poffile.INSG_Count_Faces(i); j++)
		{
			poffile.INSG_Get_Insig_Face(i, j, fcs, uv, vv);

			for (k = 0; k < 3; k++)
			{
				poffile.INSG_Get_Insig_Vertex(i, fcs[k], insignia[i].faces[j].verts[k]);
				insignia[i].faces[j].verts[k] = POFTranslate(insignia[i].faces[j].verts[k]);

				insignia[i].faces[j].u[k] = u[k];
				insignia[i].faces[j].v[k] = v[k];
			}
		}
	}

	// --------- ai_paths --------- 
	ai_paths.resize(poffile.PATH_Count_Paths());
	for (i = 0; i < poffile.PATH_Count_Paths(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Getting Path %d", i);
		progress->incrementWithMessage(cstringtemp);
		poffile.PATH_Get_Path(i, ai_paths[i].name, ai_paths[i].parent);

		ai_paths[i].verts.resize(poffile.PATH_Count_Verts(i));

		for (j = 0; j < poffile.PATH_Count_Verts(i); j++)
		{
			poffile.PATH_Get_Vert(i, j, ai_paths[i].verts[j].pos, 
										ai_paths[i].verts[j].radius);
			ai_paths[i].verts[j].pos = POFTranslate(ai_paths[i].verts[j].pos);
		}
	}

	// --------- light arrays --------- 
	light_arrays.resize(poffile.GLOW_Count_LightGroups());
	pcs_glow_array *gla;

	for (i = 0; i < poffile.GLOW_Count_LightGroups(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Getting Glow Array %d", i);
		progress->incrementWithMessage(cstringtemp);
		gla = &light_arrays[i];
		poffile.GLOW_Get_Group(i, gla->disp_time, gla->on_time, gla->off_time,
								  gla->obj_parent, gla->LOD, gla->type, gla->properties);
		gla->lights.resize(poffile.GLOW_Count_Glows(i));

		for (j = 0; j < poffile.GLOW_Count_Glows(i); j++)
		{
			poffile.GLOW_Get_GlowPoint(i, j, gla->lights[j].radius,
											 gla->lights[j].pos,
											 gla->lights[j].norm);
			gla->lights[j].pos = POFTranslate(gla->lights[j].pos);
			gla->lights[j].norm = POFTranslate(gla->lights[j].norm);
		}
	}

	// --------- Sub object Consversion ---------
	subobjects.resize(poffile.OBJ2_Count());

	if (can_bsp_cache)
		bsp_cache.resize(poffile.OBJ2_Count());
	for (i = 0; i < poffile.OBJ2_Count(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Getting Object %d", i);
		progress->incrementWithMessage(cstringtemp);

		pcs_sobj* obj = &subobjects[i];
		poffile.OBJ2_Get_Parent(i, obj->parent_sobj);
		poffile.OBJ2_Get_Radius(i, obj->radius);
		obj->radius_override = obj->radius;

		poffile.OBJ2_Get_Offset(i, obj->offset);
		obj->offset = POFTranslate(obj->offset);

		poffile.OBJ2_Get_GeoCenter(i, obj->geometric_center);
		obj->geometric_center = POFTranslate(obj->geometric_center);

		poffile.OBJ2_Get_BoundingMin(i, obj->bounding_box_min_point);

		poffile.OBJ2_Get_BoundingMax(i, obj->bounding_box_max_point);

		POFTranslateBoundingBoxes(obj->bounding_box_min_point, obj->bounding_box_max_point);
		obj->bounding_box_min_point_override = obj->bounding_box_min_point;
		obj->bounding_box_max_point_override = obj->bounding_box_max_point;

		poffile.OBJ2_Get_Name(i, obj->name);
		poffile.OBJ2_Get_Props(i, obj->properties);
		int type;
		poffile.OBJ2_Get_MoveType(i, type); // -1 = none, 1 = rotate
		switch (type)
		{
			case 1:
				obj->movement_type = ROTATE;
				break;
			default:
				obj->movement_type = MNONE;
		}
		poffile.OBJ2_Get_MoveAxis(i, type); // -1 = none, 1 = X, 2 = Z, 3 = Y
		switch (type)
		{
			case 0:
				obj->movement_axis = MV_X;
				break;
			case 1:
				obj->movement_axis = MV_Z;
				break;
			case 2:
				obj->movement_axis = MV_Y;
				break;
			default:
				obj->movement_axis = ANONE;
		}

		// fast method
		int bspsz;
		char *bspdata = NULL;
		poffile.OBJ2_Get_BSPDataPtr(i, bspsz, bspdata);

		//OBJ2_Get_BSPData

		obj->polygons.resize(100); // good starting size;

		unsigned int used_polygons = 0;
		BSP_DefPoints points;
		BSPTransPMF(0, (unsigned char *)bspdata, points, obj->polygons, used_polygons);
		obj->polygons.resize(used_polygons); // resize to exact size

		if (can_bsp_cache)
			poffile.OBJ2_Get_BSPData(i, bsp_cache[i].bsp_data);

		//if (bspdata)
		//	delete[] bspdata;
		//bspdata = NULL;
	}
	Transform(matrix(), vector3d());
	header.max_radius_overridden = std::fabs(header.max_radius - header.max_radius_override) > 0.0001f;
	header.max_bounding_overridden = header.max_bounding != header.max_bounding_override;
	header.min_bounding_overridden = header.min_bounding != header.min_bounding_override;
	for (auto& sobj : subobjects) {
		sobj.radius_overridden = std::fabs(sobj.radius - sobj.radius_override) > 0.0001f;
		sobj.bounding_box_min_point_overridden = sobj.bounding_box_min_point != sobj.bounding_box_min_point_override;
		sobj.bounding_box_max_point_overridden = sobj.bounding_box_max_point != sobj.bounding_box_max_point_override;
	}
	return 0;
}