コード例 #1
0
ファイル: xrVis.cpp プロジェクト: AntonioModer/xray-16
void CalculateRelSet(Fvector &pos, vecW &rel_set)
{
	// calculate volume in local level space
	Fbox	Volume;
	Volume.set(pos,pos);
	float	Vsize = (g_params.m_relevance+g_params.m_sample_step)/2.f; 
	Volume.min.sub(Vsize);
	Volume.max.add(Vsize);
	Volume.min.sub(g_TREE_ROOT->bbox.min);
	Volume.max.sub(g_TREE_ROOT->bbox.min);

	// scale it to sample grid space
	Volume.min.div(g_params.m_sample_step);
	Volume.max.div(g_params.m_sample_step);

	// calc volume in grid-space
	int minX,minY,minZ;
	int maxX,maxY,maxZ;

	minX = iROUND(floorf(Volume.min.x));	clamp(minX, 0, int(g_pvs_X)-1);
	minY = iROUND(floorf(Volume.min.y));	clamp(minY, 0, int(g_pvs_Y)-1);
	minZ = iROUND(floorf(Volume.min.z));	clamp(minZ, 0, int(g_pvs_Z)-1);

	maxX = iROUND(ceilf(Volume.max.x));		clamp(maxX, 0, int(g_pvs_X)-1);
	maxY = iROUND(ceilf(Volume.max.y));		clamp(maxY, 0, int(g_pvs_Y)-1);
	maxZ = iROUND(ceilf(Volume.max.z));		clamp(maxZ, 0, int(g_pvs_Z)-1);

	/*
	clMsg("- Selected BB: [%d,%d,%d]-[%d,%d,%d]",
		minX,minY,minZ,
		maxX,maxY,maxZ
		);
	*/

	// merge data
	for (int z=minZ; z<=maxZ; z++) {
		for (int x=minX; x<=maxX; x++) {
			for (int y=minY; y<=maxY; y++)
			{
				u32	cell	= z*g_pvs_X*g_pvs_Y + x*g_pvs_Y + y;
//				clMsg("* Sample #%d",cell);
				int		ptr		= g_pvs_map_vm[cell];
				if (ptr>=0)
				{
					rel_set.insert(rel_set.end(),g_pvs[ptr].begin(),g_pvs[ptr].end());
				}
			}
		}
	}
	if (rel_set.size()>1)
	{
		std::sort(rel_set.begin(),rel_set.end());
		vecW_IT I = std::unique(rel_set.begin(),rel_set.end());
		rel_set.erase(I,rel_set.end());
	}
}
コード例 #2
0
ファイル: xrPVS.cpp プロジェクト: NeoAnomaly/xray
void CBuild::BuildPVS()
{
	Fvector size;
	Fvector pos;
	Fvector	ground_dir;

	Status("Preparing...");

	g_TREE_ROOT->bbox.getsize(size);
	g_pvs_X = iROUND(ceilf(size.x/g_params.m_sample_step))+1;
	g_pvs_Y = iROUND(ceilf(size.y/g_params.m_sample_step))+1;
	g_pvs_Z = iROUND(ceilf(size.z/g_params.m_sample_step))+1;
	clMsg("Ceiling dimensions: [%3d,%3d,%3d]",g_pvs_X, g_pvs_Y, g_pvs_Z);

	// ground pick setup
	XRC.RayMode			(RAY_ONLYFIRST|RAY_CULL);
	ground_dir.set		(0,-1,0);

	// reserve memory
	CFS_File			pvs_map		("pvs.temp");
	u32				dwSlot		= 0;
	u32				dwSlotsTotal= g_pvs_X*g_pvs_Y*g_pvs_Z;
	u32	pvs_reserve	= dwSlotsTotal/1024 + 512;
	clMsg("PVS: %d M",	(pvs_reserve*sizeof(vecW))/(1024*1024));
	g_pvs.reserve		(pvs_reserve);

	// begin!
	Status("Processing...");
	u32				dwStartTime	= timeGetTime();
	for (int z=0; z<g_pvs_Z; z++) {
		for (int x=0; x<g_pvs_X; x++) {
			for (int y=0; y<g_pvs_Y; y++)
			{
				pos.set(x,y,z);
				pos.mul(g_params.m_sample_step);
				pos.add(g_TREE_ROOT->bbox.min);
				dwSlot++;
				
				// ground pick
				XRC.RayPick(precalc_identity,1.f,&RCAST_Model,pos,ground_dir,g_params.m_sample_break);
				if (XRC.GetRayContactCount()==0)
				{
					// don't calculate PVS for this point
					int tmp = -1;
					pvs_map.write(&tmp,4);
					continue;
				}

				// Sample PVS data
				g_TREE_ROOT->VisUnroll(pos,g_selected);
				if (!g_selected.empty()) {
					g_result.resize(g_selected.size());
					ZeroMemory(g_result.begin(),g_result.size()*sizeof(BOOL));
					ORM_Process(g_selected.size(),pos,g_selected.begin(),g_result.begin());
					
					// Exclude invisible
					for (int i=0; i<g_selected.size(); i++)
					{
						if (!g_result[i]) {
							if (g_tree[g_selected[i]]->isPatch) continue;
							g_selected.erase(g_selected.begin()+i);
							g_result.erase(g_result.begin()+i);
							i--;
						}
					}
				}
				
				// Compress and record PVS sample
				pvs_map.w_u32(CompressSelected());
				g_selected.clear();

				// Statistic
				if (dwSlot%64 == 63)
				{
					Progress(float(dwSlot)/float(dwSlotsTotal));
					u32 dwCurrentTime = timeGetTime();
					Status("Sample #%d\nSpeed %3.1f samples per second\nPVS entrys: %d",
						dwSlot,1000.f*float(dwSlot)/float(dwCurrentTime-dwStartTime),
						g_pvs.size()
						);

				}
			}
		}
	}
	ORM_Destroy();
	clMsg("* PVS entrys:  %d",	g_pvs.size());
	clMsg("* Aver. Speed: %3.1f",	1000.f*float(dwSlot)/float(timeGetTime()-dwStartTime));
}
コード例 #3
0
ファイル: xrVis.cpp プロジェクト: AntonioModer/xray-16
void CBuild::BuildRelevance(IWriter &fs)
{
	static Fvector size;
	static u32	nx,ny,nz;

	Status("Preparing...");
	R_ASSERT(g_TREE_ROOT);
	g_TREE_ROOT->bbox.getsize(size);
	clMsg("Level dimensions: [%3.1f,%3.1f,%3.1f]",size.x,size.y,size.z);
	nx = iROUND(ceilf(size.x/g_params.m_relevance));
	ny = iROUND(ceilf(size.y/g_params.m_relevance));
	nz = iROUND(ceilf(size.z/g_params.m_relevance));
	clMsg("Ceiling dimensions: [%3d,%3d,%3d]",nx, ny, nz);

	fs.open_chunk(fsL_VISIBILITY);
 
	fs.open_chunk(fsV_HEADER);
	V_Header		H;
	H.nX			= nx;
	H.nY			= ny;
	H.nZ			= nz;
	H.relevance		= g_params.m_relevance;
	H.min.set		(g_TREE_ROOT->bbox.min);
	fs.write		(&H,sizeof(H));
	fs.close_chunk	();

	// Build Visibility
	static xr_vector< u32 >		slots;
	static xr_vector< vecW >		vis_nodes;
	static xr_vector< vecW >		vis_lights;
	static xr_vector< vecW >		vis_glows;
	static xr_vector< vecW >		vis_occluders;
	static vecW					rel_set;
	static vecW					unroll;

	CVirtualFileStream*			pvs_map_stream=0;
	if (g_params.m_bTestOcclusion)
	{
		pvs_map_stream  = xr_new<CVirtualFileStream> ("pvs.temp");
		g_pvs_map_vm	= (int *)pvs_map_stream->Pointer();
	}
 
	static u32				dwSlot = 0;
	for (int z=0; z<nz; z++) {
		for (int x=0; x<nx; x++) {
			for (int y=0; y<ny; y++)
			{
				Status("Volume #%d...",dwSlot);
				static Fvector pos;
				pos.set(x,y,z);
				pos.add(.5f);
				pos.mul(g_params.m_relevance);
				pos.add(g_TREE_ROOT->bbox.min);

				// ******* Nodes relevance
				if (g_params.m_bTestOcclusion)
				{
					CalculateRelSet(pos,unroll);
					if (unroll.empty() || g_TREE_ROOT->VisCapture(unroll,rel_set))
						rel_set.push_back(g_tree.size()-1);
					unroll.clear();
					slots.push_back(PlaceData(vis_nodes,rel_set));
				} else {
					// Unroll hierrarhy
					VERIFY(g_TREE_ROOT);
					g_TREE_ROOT->VisUnroll(pos,unroll);
					if (unroll.size()>1)
						std::sort(unroll.begin(),unroll.end());
					// Capture results
					if (g_TREE_ROOT->VisCapture(unroll,rel_set))
						rel_set.push_back(g_tree.size()-1);
					unroll.clear();
					// Register in container
					slots.push_back(PlaceData(vis_nodes,rel_set));
				}

				// Lights relevance
				for (int i=0; i<lights.size(); i++)
				{
					if ((pos.distance_to(lights[i].position) - lights[i].range) < g_params.m_viewdist) {
						rel_set.push_back(i);
					}
				}
				slots.push_back(PlaceData(vis_lights,rel_set));

				// Glows relevance
				for (i=0; i<glows.size(); i++)
				{
					if ((pos.distance_to(glows[i].P) - glows[i].size) < g_params.m_viewdist) {
						rel_set.push_back(i);
					}
				}
				slots.push_back(PlaceData(vis_glows,rel_set));

				// Occluders relevance
				for (i=0; i<occluders.size(); i++)
				{
					Fvector P; float R=-1; float T;
					P.add(occluders[i].V2,occluders[i].V4);
					P.mul(.5f);
					T = P.distance_to(occluders[i].V1); if (T>R) R=T;
					T = P.distance_to(occluders[i].V2); if (T>R) R=T;
					T = P.distance_to(occluders[i].V4); if (T>R) R=T;
					if ((pos.distance_to(P) - R) < g_params.m_viewdist*g_params.m_occluder_rel_scale) {
						rel_set.push_back(i);
					}
				}
				slots.push_back(PlaceData(vis_occluders,rel_set));

				dwSlot++;
				Progress(float(dwSlot)/float(nz*nx*ny));
			}
		}
	}


	xr_delete		(pvs_map_stream);

	fs.open_chunk	(fsV_NODES);
	SaveDATA		(fs,vis_nodes);
	fs.close_chunk	();

	fs.open_chunk(fsV_LIGHTS);
	SaveDATA(fs,vis_lights);
	fs.close_chunk();

	fs.open_chunk(fsV_GLOWS);
	SaveDATA(fs,vis_glows);
	fs.close_chunk();

	fs.open_chunk(fsV_OCCLUDERS);
	SaveDATA(fs,vis_occluders);
	fs.close_chunk();

	fs.open_chunk(fsV_MAP);
	fs.write(slots.begin(),slots.size()*sizeof(u32));
	fs.close_chunk();

	fs.close_chunk();
}