Beispiel #1
0
void CCustomObject::AnimationDrawPath()
{
    // motion path
	VERIFY (m_Motion);
#ifdef _EDITOR
	if (EPrefs->object_flags.is(epoDrawAnimPath)){
        float fps 				= m_Motion->FPS();
        float min_t				= (float)m_Motion->FrameStart()/fps;
        float max_t				= (float)m_Motion->FrameEnd()/fps;

        Fvector 				T,r;
        u32 clr					= 0xffffffff;
        path_points.clear		();
        for (float t=min_t; (t<max_t)||fsimilar(t,max_t,EPS_L); t+=1/30.f){
            m_Motion->_Evaluate	(t,T,r);
            path_points.push_back(T);
        }

        Device.SetShader		(Device.m_WireShader);
        RCache.set_xform_world	(Fidentity);
        if (!path_points.empty())
        	DU_impl.DrawPrimitiveL		(D3DPT_LINESTRIP,path_points.size()-1,path_points.begin(),path_points.size(),clr,true,false);
        CEnvelope* E 			= m_Motion->Envelope();
        for (KeyIt k_it=E->keys.begin(); k_it!=E->keys.end(); k_it++){
            m_Motion->_Evaluate	((*k_it)->time,T,r);
            if (Device.m_Camera.GetPosition().distance_to_sqr(T)<50.f*50.f){
                DU_impl.DrawCross	(T,0.1f,0.1f,0.1f, 0.1f,0.1f,0.1f, clr,false);
                DU_impl.OutText		(T,AnsiString().sprintf("K: %3.3f",(*k_it)->time).c_str(),0xffffffff,0x00000000);
            }
        }
    }
#endif    
}
Beispiel #2
0
BOOL	SphereValid	(FvectorVec& geom, Fsphere& test)
{
	if (!f_valid(test.P.x) || !f_valid(test.R))	{
		Msg	("*** Attention ***: invalid sphere: %f,%f,%f - %f",test.P.x,test.P.y,test.P.z,test.R);
	}

	Fsphere	S	=	test;
	S.R			+=	EPS_L;
	for (FvectorIt I = geom.begin(); I!=geom.end(); I++)
		if (!S.contains(*I))	return FALSE;
	return TRUE;
}
Beispiel #3
0
int AppendVertex(FvectorVec& _points, MPoint& _pt)
{
	Fvector pt; 
	// convert from internal units to the current ui units
	MDistance dst_x	(_pt.x);
	MDistance dst_y	(_pt.y);
	MDistance dst_z	(_pt.z);
	pt.set		((float)dst_x.asMeters(),(float)dst_y.asMeters(),-(float)dst_z.asMeters());

	for (FvectorIt it=_points.begin(); it!=_points.end(); it++)
		if (it->similar(pt)) return it-_points.begin();
	_points.push_back(pt);
	return _points.size()-1;
}
Beispiel #4
0
void ComputeSphere(Fsphere &B, FvectorVec& V)
{
    if (V.size()<3) 	{ B.P.set(0,0,0); B.R=0.f; return; }

	// 1: calc first variation
	Fsphere	S1;
    Fsphere_compute		(S1,V.begin(),V.size());
	BOOL B1				= SphereValid(V,S1);
    
	// 2: calc ordinary algorithm (2nd)
	Fsphere	S2;
	Fbox bbox;
    bbox.invalidate		();
	for (FvectorIt I=V.begin(); I!=V.end(); I++)	bbox.modify(*I);
	bbox.grow			(EPS_L);
	bbox.getsphere		(S2.P,S2.R);
	S2.R = -1;
	for (I=V.begin(); I!=V.end(); I++)	{
		float d = S2.P.distance_to_sqr(*I);
		if (d>S2.R) S2.R=d;
	}
	S2.R = _sqrt (_abs(S2.R));
	BOOL B2				= SphereValid(V,S2);

	// 3: calc magic-fm
	Mgc::Sphere _S3 = Mgc::MinSphere(V.size(), (const Mgc::Vector3*) V.begin());
	Fsphere	S3;
	S3.P.set			(_S3.Center().x,_S3.Center().y,_S3.Center().z);
	S3.R				= _S3.Radius();
	BOOL B3				= SphereValid(V,S3);

	// select best one
	if (B1 && (S1.R<S2.R)){		// miniball or FM
		if (B3 && (S3.R<S1.R)){ // FM wins
        	B.set	(S3);
		}else{					// MiniBall wins
        	B.set	(S1);
		}
	}else{						// base or FM
		if (B3 && (S3.R<S2.R)){	// FM wins
        	B.set	(S3);
		}else{					// Base wins :)
        	R_ASSERT(B2);
        	B.set	(S2);
		}
	}
}
Beispiel #5
0
void ComputeCylinder(Fcylinder& C, Fobb& B, FvectorVec& V)
{
    if (V.size()<3) 	{ C.invalidate(); return; }
    // pow(area,(3/2))/volume
    // 2*Pi*R*H+2*Pi*R*R
	
//	Fvector axis;
    float max_hI   	= flt_min;
    float min_hI   	= flt_max;
    float max_rI   	= flt_min;
    float max_hJ   	= flt_min;
    float min_hJ   	= flt_max;
    float max_rJ   	= flt_min;
    float max_hK   	= flt_min;
    float min_hK   	= flt_max;
    float max_rK   	= flt_min;
    Fvector axisJ 		= B.m_rotate.j;
    Fvector axisI 		= B.m_rotate.i;
    Fvector axisK 		= B.m_rotate.k;
    Fvector& c			= B.m_translate;
    for (FvectorIt I=V.begin(); I!=V.end(); I++){
        Fvector tmp;
    	Fvector pt		= *I;
    	Fvector pt_c;	pt_c.sub(pt,c);

    	float pI		= axisI.dotproduct(pt);
        min_hI			= _min(min_hI,pI);
        max_hI			= _max(max_hI,pI);
        tmp.mad			(c,axisI,axisI.dotproduct(pt_c));
        max_rI			= _max(max_rI,tmp.distance_to(pt));
        
    	float pJ		= axisJ.dotproduct(pt);
        min_hJ			= _min(min_hJ,pJ);
        max_hJ			= _max(max_hJ,pJ);
        tmp.mad			(c,axisJ,axisJ.dotproduct(pt_c));
        max_rJ			= _max(max_rJ,tmp.distance_to(pt));

    	float pK		= axisK.dotproduct(pt);
        min_hK			= _min(min_hK,pK);
        max_hK			= _max(max_hK,pK);
        tmp.mad			(c,axisK,axisK.dotproduct(pt_c));
        max_rK			= _max(max_rK,tmp.distance_to(pt));
    }

    float hI			= (max_hI-min_hI);
    float hJ			= (max_hJ-min_hJ);
    float hK			= (max_hK-min_hK);
    float vI			= hI*M_PI*_sqr(max_rI);
    float vJ			= hJ*M_PI*_sqr(max_rJ);
    float vK			= hK*M_PI*_sqr(max_rK);
//    vI					= pow(2*M_PI*max_rI*hI+2*M_PI*_sqr(max_rI),3/2)/vI;
//    vJ					= pow(2*M_PI*max_rJ*hJ+2*M_PI*_sqr(max_rJ),3/2)/vJ;
//    vK					= pow(2*M_PI*max_rK*hK+2*M_PI*_sqr(max_rK),3/2)/vK;
    // pow(area,(3/2))/volume
    // 2*Pi*R*H+2*Pi*R*R
    
    if (vI<vJ){
    	if (vI<vK){
        	//vI;
            C.m_direction.set	(axisI);
            C.m_height			= hI;
            C.m_radius			= max_rI;
        }else{
        	// vK
            C.m_direction.set	(axisK);
            C.m_height			= hK;
            C.m_radius			= max_rK;
        }
    }else {
        //vJ < vI
     	if (vJ<vK){
        	// vJ
            C.m_direction.set	(axisJ);
            C.m_height			= hJ;
            C.m_radius			= max_rJ;
        } else {
            //vK
            C.m_direction.set	(axisK);
            C.m_height			= hK;
            C.m_radius			= max_rK;
        }
    }
    
    C.m_center.set		(B.m_translate);
/*
    if (V.size()<3) { B.invalidate(); return; }
    Mgc::Cylinder CYL	= Mgc::ContCylinder(V.size(), (const Mgc::Vector3*) V.begin());
    B.m_center.set		(CYL.Center());
    B.m_direction.set	(CYL.Direction());
    B.m_height			= CYL.Height();
    B.m_radius			= CYL.Radius();
*/
}
Beispiel #6
0
void CEditableMesh::Optimize(BOOL NoOpt)
{
	if (!NoOpt){
#ifdef _EDITOR
    	UnloadRenderBuffers	();
		UnloadCForm     	();
#endif
        UnloadFNormals   	(true);
        UnloadVNormals   	(true);
       	UnloadSVertices  	(true);
       	UnloadAdjacency		(true);
    	
		// clear static data
		for (int x=0; x<MX+1; x++)
			for (int y=0; y<MY+1; y++)
    			for (int z=0; z<MZ+1; z++)
            		VM[x][y][z].clear();
		VMscale.set(m_Box.max.x-m_Box.min.x+EPS_S, m_Box.max.y-m_Box.min.y+EPS_S, m_Box.max.z-m_Box.min.z+EPS_S);
		VMmin.set(m_Box.min.x, m_Box.min.y, m_Box.min.z);

		VMeps.set(VMscale.x/MX/2,VMscale.y/MY/2,VMscale.z/MZ/2);
		VMeps.x = (VMeps.x<EPS_L)?VMeps.x:EPS_L;
		VMeps.y = (VMeps.y<EPS_L)?VMeps.y:EPS_L;
		VMeps.z = (VMeps.z<EPS_L)?VMeps.z:EPS_L;

		m_NewPoints.clear();
		m_NewPoints.reserve(m_VertCount);
                                                
		boolVec 	faces_mark;
		faces_mark.resize(m_FaceCount,false);
        int			i_del_face 		= 0;
		for (u32 k=0; k<m_FaceCount; k++){
    		if (!OptimizeFace(m_Faces[k])){
				faces_mark[k]		= true;
                i_del_face			++;
            }
		}

        m_VertCount		= m_NewPoints.size();
        xr_free			(m_Verts);
        m_Verts			= xr_alloc<Fvector>(m_VertCount);
		Memory.mem_copy	(m_Verts,&*m_NewPoints.begin(),m_NewPoints.size()*sizeof(Fvector));

		if (i_del_face){
	        st_Face* 	old_faces 	= m_Faces;
	        u32* 		old_sg 		= m_SGs;

            m_Faces		= xr_alloc<st_Face>	(m_FaceCount-i_del_face);
            m_SGs		= xr_alloc<u32>		(m_FaceCount-i_del_face);
            
            u32 new_dk	= 0;
            for (u32 dk=0; dk<m_FaceCount; dk++){
            	if (faces_mark[dk]){
                    for (SurfFacesPairIt plp_it=m_SurfFaces.begin(); plp_it!=m_SurfFaces.end(); plp_it++){
                        IntVec& 	pol_lst = plp_it->second;
                        for (int k=0; k<int(pol_lst.size()); k++){
                            int& f = pol_lst[k];
                            if (f>(int)dk){ f--;
                            }else if (f==(int)dk){
                                pol_lst.erase(pol_lst.begin()+k);
                                k--;
                            }
                        }
                    }
                	continue;
                } 
            	m_Faces[new_dk]	= old_faces[dk];
            	m_SGs[new_dk]	= old_sg[dk];
				new_dk++;
            }
            m_FaceCount	= m_FaceCount-i_del_face;
            xr_free		(old_faces);
            xr_free		(old_sg);
		}
	}
}
Beispiel #7
0
bool CEditableMesh::OptimizeFace(st_Face& face){
	Fvector points[3];
	int mface[3];
	int k;

	for (k=0; k<3; k++){
    	points[k].set(m_Verts[face.pv[k].pindex]);
		mface[k] = -1;
    }

	// get similar vert idx list
	for (k=0; k<3; k++){
		U32Vec* vl;
		int ix,iy,iz;
		ix = iFloor(float(points[k].x-VMmin.x)/VMscale.x*MX);
		iy = iFloor(float(points[k].y-VMmin.y)/VMscale.y*MY);
		iz = iFloor(float(points[k].z-VMmin.z)/VMscale.z*MZ);
		vl = &(VM[ix][iy][iz]);
		for(U32It it=vl->begin();it!=vl->end(); it++){
			FvectorIt v = m_NewPoints.begin()+(*it);
            if( v->similar(points[k],EPS) )
                mface[k] = *it;
		}
	}
	for(k=0; k<3; k++ ){
		if( mface[k] == -1 ){
			mface[k] = m_NewPoints.size();
			m_NewPoints.push_back( points[k] );
			int ix,iy,iz;
			ix = iFloor(float(points[k].x-VMmin.x)/VMscale.x*MX);
			iy = iFloor(float(points[k].y-VMmin.y)/VMscale.y*MY);
			iz = iFloor(float(points[k].z-VMmin.z)/VMscale.z*MZ);
			VM[ix][iy][iz].push_back(mface[k]);
			int ixE,iyE,izE;
			ixE = iFloor(float(points[k].x+VMeps.x-VMmin.x)/VMscale.x*MX);
			iyE = iFloor(float(points[k].y+VMeps.y-VMmin.y)/VMscale.y*MY);
			izE = iFloor(float(points[k].z+VMeps.z-VMmin.z)/VMscale.z*MZ);
			if (ixE!=ix)
				VM[ixE][iy][iz].push_back(mface[k]);
			if (iyE!=iy)
				VM[ix][iyE][iz].push_back(mface[k]);
			if (izE!=iz)
				VM[ix][iy][izE].push_back(mface[k]);
			if ((ixE!=ix)&&(iyE!=iy))
				VM[ixE][iyE][iz].push_back(mface[k]);
			if ((ixE!=ix)&&(izE!=iz))
				VM[ixE][iy][izE].push_back(mface[k]);
			if ((iyE!=iy)&&(izE!=iz))
				VM[ix][iyE][izE].push_back(mface[k]);
			if ((ixE!=ix)&&(iyE!=iy)&&(izE!=iz))
				VM[ixE][iyE][izE].push_back(mface[k]);
		}
	}

	if ((mface[0]==mface[1])||(mface[1]==mface[2])||(mface[0]==mface[2])){
		Msg("!Optimize: Invalid face found. Removed.");
        return false;
	}else{
    	face.pv[0].pindex = mface[0];
    	face.pv[1].pindex = mface[1];
    	face.pv[2].pindex = mface[2];
        return true;
	}
}