Пример #1
0
void RenderSortnorm(unsigned int offset, unsigned char *data, vector3d obj_center)
{
	BSP_BlockHeader blkhdr;
	BSP_SortNorm snorm;
	unsigned char *curpos = data + offset;
	
	blkhdr.Read((char *) curpos);
	
	snorm.Read((char *) curpos + blkhdr.MySize(), blkhdr);

	// draw a cube defined by the bounding region
	glColor3f(1.0, 0.0, 0.0);
	OpenGL_RenderBox(POFTranslate(snorm.min_bounding_box_point), POFTranslate(snorm.max_bounding_box_point));

	// continue traversal
	if (snorm.front_offset)
		RenderBSP(offset + snorm.front_offset, data, obj_center); // continue traversal

	if (snorm.back_offset)
		RenderBSP(offset + snorm.back_offset, data, obj_center); // continue traversal

	if (snorm.prelist_offset)
		RenderBSP(offset + snorm.prelist_offset, data, obj_center); // continue traversal
	
	if (snorm.postlist_offset)
		RenderBSP(offset + snorm.postlist_offset, data, obj_center); // continue traversal

	if (snorm.online_offset)
		RenderBSP(offset + snorm.online_offset, data, obj_center); // continue traversal


	
	// No tail recursion on sortnorms
}
Пример #2
0
void RenderTextured(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_TmapPoly tpoly;
	tpoly.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(tpoly.center);
	vector3d norm = point+(POFTranslate(tpoly.normal)*5);

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

	glBegin(GL_LINE_STRIP);	
		glVertex3fv((float *)&point);
		glVertex3fv((float *)&norm);
	glEnd();
	// tail recurse
	tpoly.Destroy();
#endif
	RenderBSP(offset + blkhdr.size, data, obj_center);
}
Пример #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
}
Пример #4
0
void RenderBBox(unsigned int offset, unsigned char *data, vector3d obj_center)
{
	BSP_BlockHeader blkhdr;
	BSP_BoundBox bbox;
	unsigned char *curpos = data + offset;

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

	if (blkhdr.id != 5)
		return;
	
	glColor3f(0.0, 1.0, 0.0);
	OpenGL_RenderBox(POFTranslate(bbox.min_point), POFTranslate(bbox.max_point));


	// tail recurse
	RenderBSP(offset + blkhdr.size, data, obj_center);

}
Пример #5
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
}
Пример #6
0
void wxGL_PMFCanvas::Render()
{	
	if (FreezeRender)
		return;

	IsRendering = true;
	this->SetCurrent();

	glEnable(GL_CULL_FACE);
	glFrontFace(GL_CW);

	glClearColor(0, 0, 0, 1.0f);				// Black Background
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear Screen And Depth Buffer

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if(GetSize().GetHeight()){
		//more division by zero-Bobboau
		float asp = (float)GetSize().GetWidth()/(float)GetSize().GetHeight();

		if(proj_mode == PROJ_ORTHO){
			float z = (position.z+log(abs(position.z)+1.0f))/1.25f;
			glOrtho((asp+position.x/1000.0f)*z, (-asp+position.x/1000.0f)*z, (1.0f+position.y/1000.0f)*z, (-1.0f+position.y/1000.0f)*z, -500.0, 50000.0);
		}else{
			gluPerspective( 75.0f, asp, 1.0f, 250000.0f );
		}
	}
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	float radius;

	//position = vector3d(0,0,-(model.SOBJ(0).radius * 2.0));
	//rotation = vector3d(33,-66,0);
	if (model.GetSOBJCount())
	{
		radius = model.GetMaxRadius();
		// --------------------------------------------------------
		glTranslatef(position.x, position.y, position.z);
		// translate by autocentering point
		vector3d acen = model.GetAutoCenter();
		//glRotatef(GlobalRotation.z, 0, 0, 1);
		glTranslatef(acen.x, acen.y, acen.z);
				
		// --------------------------------------------------------
		// Setup Lighting
		glEnable(GL_LIGHTING);	
		GLfloat  ambientLight[4]; ambientLight[0] = ambient_light[0]; ambientLight[1] = ambient_light[1]; ambientLight[2] = ambient_light[2]; ambientLight[3] = ambient_light[3];
		GLfloat  diffuseLight[4]; diffuseLight[0] = diffuse_light[0]; diffuseLight[1] = diffuse_light[1]; diffuseLight[2] = diffuse_light[2]; diffuseLight[3] = diffuse_light[3];
		GLfloat  specular[]={ 1.0f, 1.0f, 1.0f, 1.0f};
		GLfloat lightPos[]={ 0.0f, radius+350.0f, (radius+350.0f), 1.0f};
		//GLfloat  specref[]= { 1.0f, 1.0f, 1.0f, 1.0f};

		// Setup and enable light 0
		glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
		glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
		glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
		glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
		glEnable(GL_LIGHT0);

		// Enable color tracking
		//glEnable(GL_COLOR_MATERIAL);


		// Render Geometry
		glRotatef(rotation.x, 1, 0, 0);
		glRotatef(rotation.y, 0, 1, 0);
		glRotatef(rotation.z, 0, 0, 1);

		if(active_chunk == TXTR)
			model.set_active_texture(omni_selected_item);
		else
			model.set_active_texture(-1);
		if (omni.lod > -1 && omni.lod < model.GetLODCount()) {
			model.set_active_model(model.LOD(omni.lod));
		}
	
		model.Render(tex_ctrl, UseVBOs, active_chunk == SOBJ);

		glTranslatef(-acen.x, -acen.y, -acen.z);

		if(active_chunk == SHLD)
			model.draw_shields();

		if(active_chunk == INSG)
			model.draw_insignia(omni.lod, omni);

		glDisable(GL_TEXTURE_2D);

		draw_omnipoints();

		glDisable(GL_LIGHTING);

		if(draw_the_grid){
			vector3d grid_point = acen;
			if(omni_selected_list >-1 && omni_selected_item >-1)//active_chunk == GPNT || active_chunk == MPNT || active_chunk == DOCK || active_chunk == FUEL || active_chunk == GLOW || active_chunk == SPCL || active_chunk == TGUN || active_chunk == EYE || active_chunk == ACEN)
				grid_point = omni.point[omni_selected_list][omni_selected_item].pos+model.get_model_offset(omni.point[omni_selected_list][omni_selected_item].model);
			vector3d POFTranslate(vector3d);
			draw_grid(POFTranslate(model.GetMinBounding())+acen, POFTranslate(model.GetMaxBounding())+acen, grid_point);
		}
	}

/*	
	vector3d V = get_eye_pos();
	vector3d U = get_eye_uvec();
	vector3d R = get_eye_rvec();
	vector3d F = get_eye_fvec();

	wxPoint pt = ScreenToClient(wxGetMousePosition());
	vector3d r = ray_cast(pt.x, pt.y);
*/
//	gr_debug->set_text(wxString::Format("Camera Position:%0.2f, %0.2f, %0.2f\nCamera Rvec:    %0.2f, %0.2f, %0.2f\nCamera Uvec:    %0.2f, %0.2f, %0.2f\nCamera Fvec:    %0.2f, %0.2f, %0.2f\n\n\nMouse Point Ray: %0.2f, %0.2f, %0.2f",V.x,V.y,V.z ,R.x,R.y,R.z ,U.x,U.y,U.z ,F.x,F.y,F.z ,r.x,r.y,r.z));
	


	this->SwapBuffers();
	IsRendering = false;
}
Пример #7
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;
}
Пример #8
0
int PCS_Model::SaveToPOF(std::string filename, AsyncProgress* progress)
{
	PCS_Model::BSP_MAX_DEPTH = 0;
	PCS_Model::BSP_NODE_POLYS = 1;
	PCS_Model::BSP_TREE_TIME = 0;
	PCS_Model::BSP_COMPILE_ERROR = false;
	POF poffile;
	unsigned int i,j,k,l;
	progress->setTarget(6 + light_arrays.size() + ai_paths.size() + insignia.size() + shield_mesh.size() + 
					thrusters.size() + docking.size() + turrets.size() + weapons.size() + special.size() +
					eyes.size() + model_info.size() + subobjects.size() + textures.size());
	char cstringtemp[256];


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

	// --------- convert cross sections --------- 
	std::vector<cross_section> sections;
	sections.resize(header.cross_sections.size());

	for (i = 0; i < header.cross_sections.size(); i++)
	{
		sections[i].depth = header.cross_sections[i].depth;
		sections[i].radius = header.cross_sections[i].radius;
	}
	poffile.HDR2_Set_CrossSections(header.cross_sections.size(), sections);

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

	// --------- ACEN --------- 
	poffile.ACEN_Set_acen(POFTranslate(autocentering));

	
	// Update Progress
	progress->incrementWithMessage("Writing Acen");
	// --------- TXTR --------- 

	
	// Update Progress
	progress->incrementWithMessage("Writing Textures");
	for (i = 0; i < textures.size(); i++)
		poffile.TXTR_AddTexture(textures[i]);

	
	// --------- Sub object Consversion ---------

	wxLongLong time = wxGetLocalTimeMillis();
	bool bsp_compiled = false;
	header.max_radius = 0.0f;
	for (i = 0; i < subobjects.size(); i++)
	{
		// Update Progress
		//if (subobjects[i].name == "debris08")
		//	sprintf(cstringtemp, "Submodel %d: %s SENTINAL!", i, subobjects[i].name.c_str());
		//else
			sprintf(cstringtemp, "Submodel %d: %s", i, subobjects[i].name.c_str());
		progress->incrementWithMessage(cstringtemp);
	
		//memset((char *)&obj, 0, sizeof(OBJ2)); this is NO LONGER ALLOWED - obj2 now contains an class w/ vtable
		boost::scoped_ptr<OBJ2> obj(new OBJ2);
		obj->submodel_number = i;
		if (!PMFObj_to_POFObj2(i, *obj, bsp_compiled, header.max_radius))
		{
			return 2; // error occured in bsp splitting!
		}
		poffile.OBJ2_Add(*obj); // takes over object management - including pointers
	}
	time = wxGetLocalTimeMillis() - time;

	// we succeeded in compiling - let's cache the result
	can_bsp_cache = true;
	bsp_cache.resize(subobjects.size());
	for (i = 0; i < subobjects.size(); i++)
		poffile.OBJ2_Get_BSPData(i, bsp_cache[i].bsp_data);


	// --------- ---------------------- ---------
	

	int idx = GetModelInfoCount();
	char cstrtmp[256];
	wxString strtmp = PCS2_VERSION;
	sprintf(cstrtmp, "PMFSaveToPOF: Compiled on %s with %s\nmax BSP depth was %d\nmost polys in a single node was %d\nTotal Compile time was %ldms, tree generation time was %ldms", std::string(strtmp.mb_str()).c_str(), std::string(PCS2_COMP_VERSION.mb_str()).c_str(), PCS_Model::BSP_MAX_DEPTH,PCS_Model::BSP_NODE_POLYS, time.ToLong(), PCS_Model::BSP_TREE_TIME.ToLong());
	
	bool found = false;
	for (i = 0; i < model_info.size() && !found; i++)
	{
		if (strstr(model_info[i].c_str(), "PMFSaveToPOF") != NULL)
		{
			found = true;
			if (bsp_compiled) // update the string
				model_info[i] = cstrtmp;
		}
	}

	if (!found)
		AddModelInfo(cstrtmp);

	j = 0;
	for (i = 0; i < model_info.size(); i++)
		j += model_info[i].length() + 1;
	
	boost::scoped_ptr<char> pinf(new char[j]);
	memset(pinf.get(), 0, j);
	j = 0;

	for (i = 0; i < model_info.size(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Writing String %d", i); 
		progress->incrementWithMessage(cstringtemp);

		strncpy(pinf.get()+j, model_info[i].c_str(), model_info[i].length());
		j+= model_info[i].length() + 1;
	}
	poffile.PINF_Set(pinf.get(), j);

	if (found)
		model_info.resize(idx); // back down to size

	// ---------  EYE --------- 

	for (i = 0; i < eyes.size(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Writing Eye %d", i);
		progress->incrementWithMessage(cstringtemp);
		poffile.EYE_Add_Eye(eyes[i].sobj_number, 
							POFTranslate(eyes[i].sobj_offset), 
							POFTranslate(eyes[i].normal));
	}


	// --------- SPCL --------- 	

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

	k = l = 0;
	// --------- weapons (GPNT/MPNT) --------- 
	for (i = 0; i < weapons.size(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Writing Weapon %d", i);
		progress->incrementWithMessage(cstringtemp);
		if (weapons[i].type == GUN)
		{
			poffile.GPNT_AddSlot();

			for (j = 0; j < weapons[i].muzzles.size(); j++)
			{
				poffile.GPNT_AddPoint(k, POFTranslate(weapons[i].muzzles[j].point),
										 POFTranslate(weapons[i].muzzles[j].norm));
			}
			k++;
		}
		else
		{	poffile.MPNT_AddSlot();

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

	// --------- turrets TGUN/TMIS --------- 
	k = l = 0;

	for (i = 0; i < turrets.size(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Writing Turret %d", i);
		progress->incrementWithMessage(cstringtemp);
		if (turrets[i].type == GUN)
		{
			poffile.TGUN_Add_Bank(turrets[i].sobj_parent, 
								  turrets[i].sobj_par_phys, 
								  POFTranslate(turrets[i].turret_normal));
			for (j = 0; j < turrets[i].fire_points.size(); j++)
			{
				poffile.TGUN_Add_FirePoint(k, POFTranslate(turrets[i].fire_points[j]));
			}
			k++;
		}
		else
		{
			poffile.TMIS_Add_Bank(turrets[i].sobj_parent, 
								  turrets[i].sobj_par_phys, 
								  POFTranslate(turrets[i].turret_normal));
			for (j = 0; j < turrets[i].fire_points.size(); j++)
			{
				poffile.TMIS_Add_FirePoint(l, POFTranslate(turrets[i].fire_points[j]));
			}
			l++;
		}
	}

	// --------- docking --------- 
	for (i = 0; i < docking.size(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Writing Docking %d", i);
		progress->incrementWithMessage(cstringtemp);
		poffile.DOCK_Add_Dock(docking[i].properties);

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

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

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

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

	// --------- shield_mesh --------- 
	int fcs[3], nbs[3];
	std::vector<vector3d> points(shield_mesh.size()*3);
	vector3d shldtvect;

	// make points list
	l = 0;
	for (i = 0; i < shield_mesh.size(); i++)
	{
		for (j = 0; j < 3; j++)
		{
			bool found_corner = false;
			for (auto& p : points)
			{
				if (p == POFTranslate(shield_mesh[i].corners[j]))
				{
					found_corner = true;
					break;
				}
			}
			if (!found_corner)
			{
				if (l >= points.size())
					points.resize(points.size()*2);
				points[l] = POFTranslate(shield_mesh[i].corners[j]);
				l++;
			}
		}
	}
	points.resize(l);

	// translate shield mesh
	for (i = 0; i < shield_mesh.size(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Writing Shield Tri %d", i);
		progress->incrementWithMessage(cstringtemp);
		// adds points to list if need, determine fcs[]
		for (j = 0; j < 3; j++)
		{
			shldtvect = POFTranslate(shield_mesh[i].corners[j]);
			fcs[j] = FindInList(points, shldtvect);
		}

		// determine neighbors (nbs[])
		j=0;
		for (k = 0; k < shield_mesh.size() && j < 3; k++)
		{
			if (Neighbor(shield_mesh[i], shield_mesh[k]) && i != k)
			{
				nbs[j] = k;
				j++;
			}
		}
		// add
		poffile.SHLD_Add_Face(POFTranslate(shield_mesh[i].face_normal), fcs, nbs);
	}

	// add points
	// Update Progress
	progress->incrementWithMessage("Writing Shield Points");
	for (i = 0; i < points.size(); i++)
		poffile.SHLD_Add_Vertex(points[i]);

	
	progress->incrementWithMessage("Writing Shield Collision Tree");
	// --------------- generate shield collision tree ----------------
	if (poffile.SHLD_Count_Faces() > 0)
	{
		std::vector<pcs_polygon> shldmesh(poffile.SHLD_Count_Faces());

		// make a pcs_polygon mesh from the shields
		for (i = 0; i < shldmesh.size(); i++)
		{
			shldmesh[i].verts.resize(3);

			poffile.SHLD_Get_Face(i, shldmesh[i].norm, fcs, nbs);

			for (j = 0; j < 3; j++)
			{
				 poffile.SHLD_Get_Vertex(fcs[j], shldmesh[i].verts[j].point);
				 shldmesh[i].verts[j].norm = shldmesh[i].norm;
			}
			
			shldmesh[i].centeroid = PolygonCenter(shldmesh[i]);
		}

		// make the tree
		vector3d smin, smax;
		std::unique_ptr<bsp_tree_node> shld_root = MakeTree(shldmesh, smax, smin);

		// pack the tree
		int sldc_size = CalcSLDCTreeSize(shld_root.get());
		std::vector<char> sldc;
		sldc.resize(sldc_size);
		
		PackTreeInSLDC(shld_root.get(), 0, &sldc.front(), sldc_size);

		poffile.SLDC_SetTree(std::move(sldc)); // POFHandler will steal our copy of the buffer
	}

	// --------- insignia --------- 

	vector3d uv, vv;
	float *u = (float *)&uv, *v = (float *)&vv;
	for (i = 0; i < insignia.size(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Writing Insignia %d", i);
		progress->incrementWithMessage(cstringtemp);
		poffile.INSG_Add_insignia(insignia[i].lod, POFTranslate(insignia[i].offset));

		for (j = 0; j < insignia[i].faces.size(); j++)
		{
			for (k = 0; k < 3; k++)
			{
				while ((l = poffile.INST_Find_Vert(i, POFTranslate(insignia[i].faces[j].verts[k]))) == (unsigned)-1)
				{
					poffile.INSG_Add_Insig_Vertex(i, POFTranslate(insignia[i].faces[j].verts[k]));
				} 
				fcs[k] = l;
				u[k] = insignia[i].faces[j].u[k];
				v[k] = insignia[i].faces[j].v[k];
			}
			poffile.INSG_Add_Insig_Face(i, fcs, uv, vv);
		}
	}

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

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

	// --------- light arrays --------- 
	pcs_glow_array *gla;
	for (i = 0; i < light_arrays.size(); i++)
	{
		// Update Progress
		sprintf(cstringtemp, "Writing Glow %d", i);
		progress->incrementWithMessage(cstringtemp);
		gla = &light_arrays[i];
		poffile.GLOW_Add_LightGroup(gla->disp_time, gla->on_time, gla->off_time,
								    gla->obj_parent, gla->LOD, gla->type, gla->properties);
		for (j = 0; j < gla->lights.size(); j++)
		{
			poffile.GLOW_Add_GlowPoint(i, gla->lights[j].radius,
										  POFTranslate(gla->lights[j].pos),
										  POFTranslate(gla->lights[j].norm));
		}
	}

	// --------- HDR2 --------- 
	
	// let's make new BBoxes based on the subobjects
	vector3d minbox, maxbox, tmpmin, tmpmax;
	poffile.OBJ2_Get_BoundingMax(0, maxbox);
	poffile.OBJ2_Get_BoundingMin(0, minbox);

	for (i = 1; i < poffile.OBJ2_Count(); i++)
	{
		vector3d sobj_offset(POFTranslate(OffsetFromParent(i)));
		poffile.OBJ2_Get_BoundingMax(i, tmpmax);
		poffile.OBJ2_Get_BoundingMin(i, tmpmin);
		ExpandBoundingBoxes(maxbox, minbox, tmpmax + sobj_offset);
		ExpandBoundingBoxes(maxbox, minbox, tmpmin + sobj_offset);

	}

	for (i = 0; i < poffile.SHLD_Count_Vertices(); i++)
	{
		poffile.SHLD_Get_Vertex(i, tmpmax);
		ExpandBoundingBoxes(maxbox, minbox, tmpmax);
	}

	// update our bounding boxes
	//axis doesn't matter on the bounding boxes - it's all negative/positive values! i'm a faqing moron
	poffile.HDR2_Set_MinBound(header.min_bounding_overridden ? header.min_bounding_override : minbox);
	poffile.HDR2_Set_MaxBound(header.max_bounding_overridden ? header.max_bounding_override : maxbox);
	this->header.max_bounding = minbox;
	this->header.min_bounding = maxbox;

	poffile.HDR2_Set_MaxRadius(header.max_radius_overridden ? header.max_radius_override : header.max_radius);
	poffile.HDR2_Set_Details(header.detail_levels.size(), header.detail_levels);
	poffile.HDR2_Set_Debris(header.debris_pieces.size(), header.debris_pieces);
	poffile.HDR2_Set_Mass(header.mass);
	poffile.HDR2_Set_MassCenter(POFTranslate(header.mass_center));
	poffile.HDR2_Set_MomentInertia(header.MOI);
	poffile.HDR2_Set_SOBJCount(GetSOBJCount());

	std::ofstream out(filename.c_str(), std::ios::out | std::ios::binary);

	if (!poffile.SavePOF(out))
		return 1;

	return 0;
}
Пример #9
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;
}