Exemple #1
0
void CreateLog			(BOOL nl)
{
    no_log				= nl;
    strconcat			(logFName,Core.ApplicationName,"_",Core.UserName,".log");
    if (FS.path_exist("$logs$"))
        FS.update_path	(logFName,"$logs$",logFName);
    if (!no_log) {
        IWriter *f		= FS.w_open	(logFName);
        if (f==NULL) {
            MessageBox	(NULL,"Can't create log file.","Error",MB_ICONERROR);
            abort();
        }
        FS.w_close		(f);
    }
    LogFile.reserve		(128);

    // Calculating build
    time_t	Time;
    time	(&Time);
    int build=0, mnum=0, dnum, ynum, mcnt;
    char mon[4];
    char buf[128];
    strcpy(buf,__DATE__);
    sscanf(buf,"%s %d %d",mon,&dnum, &ynum);
    for (int i=0; i<12; i++) {
        if (stricmp(month[i],mon)==0) mnum=i;
    }
    for (mcnt=6; mcnt<mnum; mcnt++) build+=day_in_month[mcnt];
    build+=dnum;
    Msg("'%s' build %d, %s\n","xrCore",build+(ynum-1999)*365, __DATE__);
}
void transfer(const char *name, xr_vector<T> &dest, IReader& F, u32 chunk)
{
	IReader*	O	= F.open_chunk(chunk);
	u32		count	= O?(O->length()/sizeof(T)):0;
	clMsg			("* %16s: %d",name,count);
	if (count)  
	{
		dest.reserve(count);
		dest.insert	(dest.begin(), (T*)O->pointer(), (T*)O->pointer() + count);
	}
	if (O)		O->close	();
}
Exemple #3
0
void CDeflector::RemapUV	(xr_vector<UVtri>& dest, u32 base_u, u32 base_v, u32 size_u, u32 size_v, u32 lm_u, u32 lm_v, BOOL bRotate)
{
	dest.clear	();
	dest.reserve(UVpolys.size());
	
	// UV rect (actual)
	Fvector2		a_min,a_max,a_size;
	GetRect		(a_min,a_max);
	a_size.sub	(a_max,a_min);
	
	// UV rect (dedicated)
	Fvector2		d_min,d_max,d_size;
	d_min.x		= (float(base_u)+.5f)/float(lm_u);
	d_min.y		= (float(base_v)+.5f)/float(lm_v);
	d_max.x		= (float(base_u+size_u)-.5f)/float(lm_u);
	d_max.y		= (float(base_v+size_v)-.5f)/float(lm_v);
	if (d_min.x>=d_max.x)	{ d_min.x=d_max.x=(d_min.x+d_max.x)/2; d_min.x-=EPS_S; d_max.x+=EPS_S; }
	if (d_min.y>=d_max.y)	{ d_min.y=d_max.y=(d_min.y+d_max.y)/2; d_min.y-=EPS_S; d_max.y+=EPS_S; }
	d_size.sub	(d_max,d_min);
	
	// Remapping
	Fvector2		tc;
	UVtri		tnew;
	if (bRotate)	{
		for (UVIt it = UVpolys.begin(); it!=UVpolys.end(); it++)
		{
			UVtri&	T	= *it;
			tnew.owner	= T.owner;
			for (int i=0; i<3; i++) 
			{
				tc.x = ((T.uv[i].y-a_min.y)/a_size.y)*d_size.x + d_min.x;
				tc.y = ((T.uv[i].x-a_min.x)/a_size.x)*d_size.y + d_min.y;
				tnew.uv[i].set(tc);
			}
			dest.push_back	(tnew);
		}
	} else {
		for (UVIt it = UVpolys.begin(); it!=UVpolys.end(); it++)
		{
			UVtri&	T	= *it;
			tnew.owner	= T.owner;
			for (int i=0; i<3; i++) 
			{
				tc.x = ((T.uv[i].x-a_min.x)/a_size.x)*d_size.x + d_min.x;
				tc.y = ((T.uv[i].y-a_min.y)/a_size.y)*d_size.y + d_min.y;
				tnew.uv[i].set(tc);
			}
			dest.push_back	(tnew);
		}
	}
}
Exemple #4
0
BOOL QuadFit(u32 Base, u32 Size)
{
	// ***** build horizontal line
	vecDW			BaseLine;
	BaseLine.reserve(Size);
	
	// middle
	vertex&			BaseNode = g_nodes[Base];
	BaseLine.push_back(Base);
	
	// right expansion
	for (; BaseLine.size()<Size; ) 
	{
		vertex&	B	= g_nodes[BaseLine.back()];
		u32	RP	= B.nRight();
		
		if (RP==InvalidNode)					break;
		if (used[RP])							break;
		if (!NodeSimilar(BaseNode,g_nodes[RP]))	break;
		
		BaseLine.push_back(RP);
	}
	if (BaseLine.size()<Size)	return FALSE;
	
	// down expansion
	BestQuad.clear	();
	BestQuad_Count	= 0;
	BestQuad.reserve		(Size);
	BestQuad.push_back		(BaseLine);
	
	for (; BestQuad.size() < Size;) {
		// create _new list
		BestQuad.push_back	(vecDW());
		vecDW&	src			= BestQuad[BestQuad.size()-2];
		vecDW&	dest		= BestQuad[BestQuad.size()-1];
		dest.reserve		(Size);
		
		// iterate on it
		vecDW_it I			= src.begin	();
		vecDW_it E			= src.end	();
		for (; I!=E; I++)
		{
			u32	id	= g_nodes[*I].nBack();
			if	(id==InvalidNode)						return FALSE;
			if	(used[id])								return FALSE;
			if	(!NodeSimilar(g_nodes[id],BaseNode))	return FALSE;
			dest.push_back	(id);
		}
	}
	return TRUE;
}
Exemple #5
0
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));
}
BOOL ESceneAIMapTool::CreateNode(Fvector& vAt, SAINode& N, bool bIC)
{
	// *** Query and cache polygons for ray-casting
	Fvector	PointUp;		PointUp.set(vAt);	PointUp.y	+= RCAST_Depth;		SnapXZ	(PointUp,m_Params.fPatchSize);
	Fvector	PointDown;		PointDown.set(vAt);	PointDown.y	-= RCAST_Depth;		SnapXZ	(PointDown,m_Params.fPatchSize);

	Fbox	BB;				BB.set	(PointUp,PointUp);		BB.grow(m_Params.fPatchSize/2);	// box 1
	Fbox	B2;				B2.set	(PointDown,PointDown);	B2.grow(m_Params.fPatchSize/2);	// box 2
	BB.merge				(B2);

    if (m_CFModel)
    {
    	/*
        for(u32 i=0; i<m_CFModel->get_tris_count(); ++i)
        {
            CDB::TRI* tri = (m_CFModel->get_tris()+i);
            if(tri->material!=0)
            	Msg("non-default material");
        }
        */
    	Scene->BoxQuery(PQ,BB,CDB::OPT_FULL_TEST,m_CFModel);
    }else
    	Scene->BoxQuery(PQ,BB,CDB::OPT_FULL_TEST,GetSnapList());

	DWORD	dwCount 		= PQ.r_count();
	if (dwCount==0){
//		Log("chasm1");
		return FALSE;			// chasm?
	}

	// *** Transfer triangles and compute sector
//	R_ASSERT(dwCount<RCAST_MaxTris);
	static xr_vector<tri> tris;	tris.reserve(RCAST_MaxTris);	tris.clear();
	for (DWORD i=0; i<dwCount; i++)
	{
    	SPickQuery::SResult* R = PQ.r_begin()+i;

        if (R->e_obj&&R->e_mesh)
        {
            CSurface* surf		= R->e_mesh->GetSurfaceByFaceID(R->tag);
//.			SGameMtl* mtl 		= GMLib.GetMaterialByID(surf->_GameMtl());
//.			if (mtl->Flags.is(SGameMtl::flPassable))continue;


            Shader_xrLC* c_sh	= Device.ShaderXRLC.Get(surf->_ShaderXRLCName());
            if (!c_sh->flags.bCollision) 			continue;
        }
  /*
		if(m_CFModel)
        {
            u16 mtl_id 	= R->material;

            if(std::find(m_ignored_materials.begin(), m_ignored_materials.end(), mtl_id) != m_ignored_materials.end() )
            {
//.                Msg("--ignore");
                continue;
            }
        }
*/
    	tris.push_back	(tri());
		tri&		D = tris.back();
		Fvector*	V = R->verts;   

		D.v[0]		= &V[0];
		D.v[1]		= &V[1];
		D.v[2]		= &V[2];
		D.N.mknormal(*D.v[0],*D.v[1],*D.v[2]);
		if (D.N.y<=0)	tris.pop_back	();
	}
	if (tris.size()==0){
//		Log("chasm2");
		return FALSE;			// chasm?
	}

	static xr_vector<Fvector>	points;		points.reserve(RCAST_Total); points.clear();
	static xr_vector<Fvector>	normals;	normals.reserve(RCAST_Total);normals.clear();
	Fvector P,D; D.set(0,-1,0);

	float coeff 	= 0.5f*m_Params.fPatchSize/float(RCAST_Count);

	for (int x=-RCAST_Count; x<=RCAST_Count; x++) 
	{
		P.x = vAt.x + coeff*float(x); 
		for (int z=-RCAST_Count; z<=RCAST_Count; z++) {
			P.z = vAt.z + coeff*float(z);
			P.y = vAt.y + 10.f;

			float	tri_min_range	= flt_max;
			int		tri_selected	= -1;
			float	range,u,v;
			for (i=0; i<DWORD(tris.size()); i++){
				if (ETOOLS::TestRayTriA(P,D,tris[i].v,u,v,range,false)){
					if (range<tri_min_range){
						tri_min_range	= range;
						tri_selected	= i;
					}
				}
			}
			if (tri_selected>=0) {
				P.y -= tri_min_range;
				points.push_back(P);
				normals.push_back(tris[tri_selected].N);
			}
		}
	}
	if (points.size()<3) {
//		Msg		("Failed to create node at [%f,%f,%f].",vAt.x,vAt.y,vAt.z);
		return	FALSE;
	}
//.
	float rc_lim = bIC?0.015f:0.7f;
	if (float(points.size())/float(RCAST_Total) < rc_lim) {
//		Msg		("Partial chasm at [%f,%f,%f].",vAt.x,vAt.y,vAt.z);
		return	FALSE;
	}

	// *** Calc normal
	Fvector vNorm;
	vNorm.set(0,0,0);
	for (DWORD n=0; n<normals.size(); n++)
		vNorm.add(normals[n]);
	vNorm.div(float(normals.size()));
	vNorm.normalize();
	/*
	{
		// second algorithm (Magic)
		Fvector N,O;
		N.set(vNorm);
		O.set(points[0]);
		Mgc::OrthogonalPlaneFit(
			points.size(),(Mgc::Vector3*)points.begin(),
			*((Mgc::Vector3*)&O),
			*((Mgc::Vector3*)&N)
		);
		if (N.y<0) N.invert();
		N.normalize();
		vNorm.lerp(vNorm,N,.3f);
		vNorm.normalize();
	}
	*/

 
	// *** Align plane
	Fvector vOffs;
	vOffs.set(0,-1000,0);
	Fplane PL; 	PL.build(vOffs,vNorm);
	for (DWORD p=0; p<points.size(); p++)
	{
		float dist = PL.classify(points[p]);
		if (dist>0) {
			vOffs = points[p];
			PL.build(vOffs,vNorm);
		}
	}

	// *** Create node and register it
	N.Plane.build	(vOffs,vNorm);					// build plane
	D.set			(0,1,0);
	N.Plane.intersectRayPoint(PointDown,D,N.Pos);	// "project" position

	// *** Validate results
	vNorm.set(0,1,0);
	if (vNorm.dotproduct(N.Plane.n)<_cos(deg2rad(60.f)))  return FALSE;

	float y_old = vAt.y;
	float y_new = N.Pos.y;
	if (y_old>y_new) {
		// down
		if (y_old-y_new > m_Params.fCanDOWN ) return FALSE;
	} else {
		// up
		if (y_new-y_old > m_Params.fCanUP	) return FALSE;
	}
 
	// *** Validate plane
	{
		Fvector PLP; D.set(0,-1,0);
		int num_successed_rays = 0;
		for (int x=-RCAST_Count; x<=RCAST_Count; x++) 
		{
			P.x = N.Pos.x + coeff*float(x);
			for (int z=-RCAST_Count; z<=RCAST_Count; z++) {
				P.z = N.Pos.z + coeff*float(z);
				P.y = N.Pos.y;
				N.Plane.intersectRayPoint(P,D,PLP);	// "project" position
				P.y = PLP.y+RCAST_VALID*0.01f;
				
				float	tri_min_range	= flt_max;
				int		tri_selected	= -1;
				float	range,u,v;
				for (i=0; i<tris.size(); i++){
					if (ETOOLS::TestRayTriA(P,D,tris[i].v,u,v,range,false)){
						if (range<tri_min_range){
							tri_min_range	= range;
							tri_selected	= i;
						}
					}
				}
				if (tri_selected>=0){
					if (tri_min_range<RCAST_VALID) num_successed_rays++;
				}
			}
		}
		float perc = float(num_successed_rays)/float(RCAST_Total);
//.		if (!bIC&&(perc < 0.5f)){
		float perc_lim = bIC?0.015f:0.5f;
		if (perc < perc_lim){
			//			Msg		("Floating node.");
			return	FALSE;
		}
	}

	// *** Mask check
	// ???

	return TRUE;
}
Exemple #7
0
						wm_slot		(ref_shader sh)	{shader=sh;static_items.reserve(256);skeleton_items.reserve(256);}
Exemple #8
0
void ProcessOne		(u32 Base, u32 limit=8)
{
	BestQuad.clear	();
	BestQuad_Count	= 0;
	
	// ***** build horizontal line
	vecDW			BaseLine;
	BaseLine.reserve(limit*2);
	u32			BL_Left=0,BL_Right=0;
	
	// middle
	vertex&			BaseNode = g_nodes[Base];
	BaseLine.push_back(Base);
	
	// left expansion
	for (;;) {
		vertex&	B	= g_nodes[BaseLine.front()];
		u32	LP	= B.nLeft();
		
		if (BL_Left>limit)						break;
		if (LP==InvalidNode)					break;
		if (used[LP])							break;
		if (!NodeSimilar(BaseNode,g_nodes[LP]))	break;
		
		BL_Left	++;
		BaseLine.insert(BaseLine.begin(),LP);
	}
	
	// right expansion
	for (;;) {
		vertex&	B	= g_nodes[BaseLine.back()];
		u32	RP	= B.nRight();
		
		if (BL_Right>limit)						break;
		if (RP==InvalidNode)					break;
		if (used[RP])							break;
		if (!NodeSimilar(BaseNode,g_nodes[RP]))	break;
		
		BL_Right++;
		BaseLine.push_back(RP);
	}
	
	// main cycle
	//	Msg("- ---");
	u32	BasePos	= BaseLine[BL_Left];
	for (u32 left=0; left<=BL_Left; left++)
	{
		u32	limit_right	= left+limit-1;
		if (limit_right>=BaseLine.size())	limit_right=BaseLine.size()-1;
		u32	limit_left	= left;
		if (limit_left<BL_Left)				limit_left = BL_Left;
		if (limit_left>limit_right)			limit_left = limit_right;
		for (int right=int(limit_right); right>=int(limit_left); right--)
		{
			// now we have range [left,right]
			// expand it up and down
			xr_vector<vecDW>	stack_up;
			xr_vector<vecDW>	stack_down;
			
			//			Msg("[%2d,%2d], %d",	left,right,BaseLine.size());
			
			stack_up.reserve		(limit);
			stack_up.push_back		(vecDW());
			stack_up.back().assign	(BaseLine.begin()+left,BaseLine.begin()+right+1);
			stack_down.reserve		(limit);
			stack_down.push_back	(vecDW());
			stack_down.back().assign(BaseLine.begin()+left,BaseLine.begin()+right+1);
			
			// expand up
			for (;stack_up.size()<=limit;) {
				// create _new list
				stack_up.push_back	(vecDW());
				vecDW&	src			= stack_up[stack_up.size()-2];
				vecDW&	dest		= stack_up[stack_up.size()-1];
				dest.reserve		(limit);
				BOOL				bFailed = FALSE;
				
				// iterate on it
				vecDW_it I			= src.begin	();
				vecDW_it E			= src.end	();
				for (; I!=E; I++)
				{
					u32	id	= g_nodes[*I].nForward();
					if	(id==InvalidNode)					{ bFailed=TRUE; break; }
					if	(used[id])							{ bFailed=TRUE; break; }
					if	(!NodeSimilar(g_nodes[id],BaseNode)){ bFailed=TRUE; break; }
					dest.push_back	(id);
				}
				if (bFailed) {
					stack_up.pop_back();
					break;
				}
			}
			// expand down
			for (; (stack_up.size()+stack_down.size()-1) <= limit;) {
				// create _new list
				stack_down.push_back(vecDW());
				vecDW&	src			= stack_down[stack_down.size()-2];
				vecDW&	dest		= stack_down[stack_down.size()-1];
				dest.reserve		(limit);
				BOOL				bFailed = FALSE;
				
				// iterate on it
				vecDW_it I			= src.begin	();
				vecDW_it E			= src.end	();
				for (; I!=E; I++)
				{
					u32	id	= g_nodes[*I].nBack();
					if	(id==InvalidNode)					{ bFailed=TRUE; break; }
					if	(used[id])							{ bFailed=TRUE; break; }
					if	(!NodeSimilar(g_nodes[id],BaseNode)){ bFailed=TRUE; break; }
					dest.push_back	(id);
				}
				if (bFailed) {
					stack_down.pop_back();
					break;
				}
			}
			
			// calculate size
			u32 size_z	= stack_up.size()+stack_down.size()-1;
			u32 size_x	= stack_up.back().size();
			u32 size_mix	= size_z*size_x;
			if (size_mix>BestQuad_Count)	
			{
				BestQuad_Count		= size_mix;
				BestQuad.clear		();
				BestQuad.reserve	(size_z);
				
				// transfer quad
				for (u32 it=stack_up.size()-1; it>0; it--)
					BestQuad.push_back(stack_up[it]);
				BestQuad.insert(BestQuad.begin(),stack_down.begin(),stack_down.end());
			}
		}
	}
}