예제 #1
0
void EDetailManager::InvalidateSlots()
{
	int slot_cnt = dtH.size_x*dtH.size_z;
	for (int k=0; k<slot_cnt; k++){
    	DetailSlot* it = &dtSlots[k];
    	it->w_id(0,DetailSlot::ID_Empty);
    	it->w_id(1,DetailSlot::ID_Empty);
    	it->w_id(2,DetailSlot::ID_Empty);
    	it->w_id(3,DetailSlot::ID_Empty);
    }
    InvalidateCache();
}
예제 #2
0
void EDetailManager::UpdateSlotBBox(int sx, int sz, DetailSlot& slot)
{
	Fbox bbox;
    Frect rect;
    GetSlotRect			(rect,sx,sz);
    bbox.min.set		(rect.x1, m_BBox.min.y, rect.y1);
    bbox.max.set		(rect.x2, m_BBox.max.y, rect.y2);

    SBoxPickInfoVec pinf;
    ETOOLS::box_options(0);
    if (Scene->BoxPickObjects(bbox,pinf,&m_SnapObjects)){
		bbox.grow		(EPS_L_VAR);
    	Fplane			frustum_planes[4];
		frustum_planes[0].build(bbox.min,left_vec);
		frustum_planes[1].build(bbox.min,back_vec);
		frustum_planes[2].build(bbox.max,right_vec);
		frustum_planes[3].build(bbox.max,fwd_vec);

        CFrustum frustum;
        frustum.CreateFromPlanes(frustum_planes,4);

        float y_min		= flt_max;
        float y_max		= flt_min;
		for (SBoxPickInfoIt it=pinf.begin(); it!=pinf.end(); it++){
        	for (int k=0; k<(int)it->inf.size(); k++){
                float range;
                Fvector verts[3];
                it->e_obj->GetFaceWorld(it->s_obj->_Transform(),it->e_mesh,it->inf[k].id,verts);
                sPoly sSrc	(verts,3);
                sPoly sDest;
                sPoly* sRes = frustum.ClipPoly(sSrc, sDest);
                if (sRes){
                    for (u32 k=0; k<sRes->size(); k++){
                        float H = (*sRes)[k].y;
                        if (H>y_max) y_max = H+0.03f;
                        if (H<y_min) y_min = H-0.03f;
                    }
                    slot.w_y	(y_min,y_max-y_min);
                    slot.w_id(0,DetailSlot::ID_Empty);
                    slot.w_id(1,DetailSlot::ID_Empty);
                    slot.w_id(2,DetailSlot::ID_Empty);
                    slot.w_id(3,DetailSlot::ID_Empty);
                }
            }
	    }
    }else{
    	ZeroMemory(&slot,sizeof(DetailSlot));
    	slot.w_id(0,DetailSlot::ID_Empty);
    	slot.w_id(1,DetailSlot::ID_Empty);
    	slot.w_id(2,DetailSlot::ID_Empty);
    	slot.w_id(3,DetailSlot::ID_Empty);
    }
}
예제 #3
0
bool EDetailManager::UpdateSlotObjects(int x, int z){
    srand(time(NULL));

    DetailSlot* slot	= dtSlots+z*dtH.size_x+x;
    Irect		R;
    GetSlotTCRect(R,x,z);
    //ELog.Msg(mtInformation,"TC [%d,%d]-[%d,%d]",R.x1,R.y1,R.x2,R.y2);
    SIndexDistVec best;
    // find best color index
    {
        for (int v=R.y1; v<=R.y2; v++){
            for (int u=R.x1; u<=R.x2; u++){
                u32 clr;
                if (m_Base.GetColor(clr,u,v)){
                    Fcolor C;
                    C.set(clr);
                    FindClosestIndex(C,best);
                }
            }
        }
    }
    std::sort(best.begin(),best.end(),CompareWeightFunc);
    // пройдем по 4 частям слота и определим плотность заполнения (учесть переворот V)
    Irect P[4];
    float dx=float(R.x2-R.x1)/2.f;
    float dy=float(R.y2-R.y1)/2.f;

//	2 3
//	0 1
    P[0].x1=R.x1; 		  			P[0].y1=iFloor(R.y1+dy+0.501f); P[0].x2=iFloor(R.x1+dx+.499f);	P[0].y2=R.y2;
    P[1].x1=iFloor(R.x1+dx+0.501f);	P[1].y1=iFloor(R.y1+dy+0.501f);	P[1].x2=R.x2; 					P[1].y2=R.y2;
    P[2].x1=R.x1; 		  			P[2].y1=R.y1; 		  			P[2].x2=iFloor(R.x1+dx+.499f); 	P[2].y2=iFloor(R.y1+dy+.499f);
    P[3].x1=iFloor(R.x1+dx+0.501f); P[3].y1=R.y1;		  			P[3].x2=R.x2; 					P[3].y2=iFloor(R.y1+dx+.499f);

    for (int part=0; part<4; part++){
        float	alpha=0;
        int 	cnt=0;
        for (int v=P[part].y1; v<=P[part].y2; v++){
            for (int u=P[part].x1; u<=P[part].x2; u++){
                u32 clr;
                if (m_Base.GetColor(clr,u,v)){
                    Fcolor C;
                    C.set(clr);
                    CalcClosestCount(part,C,best);
                    alpha+=C.a;
                    cnt++;
                }
            }
        }
        alpha/=(cnt?float(cnt):1);
        alpha*=0.5f;
        for (u32 i=0; i<best.size(); i++)
            best[i].dens[part] = cnt?(best[i].cnt[part]*alpha)/float(cnt):0;
    }

    // fill empty slots
    R_ASSERT(best.size());
    int id=-1;
    u32 o_cnt=0;
    for (u32 i=0; i<best.size(); i++)
        o_cnt+=m_ColorIndices[best[i].index].size();
    // равномерно заполняем пустые слоты
    if (o_cnt>best.size()){
        while (best.size()<4){
            do{
	            id++;
                if (id>3) id=0;
            }while(m_ColorIndices[best[id].index].size()<=1);
			best.push_back(SIndexDist());
            best.back()=best[id];
            if (best.size()==o_cnt) break;
        }
    }

    // заполним палитру и установим Random'ы
//	Msg("Slot: %d %d",x,z);
    for(u32 k=0; k<best.size(); k++){
     	// objects
		ColorIndexPairIt CI=m_ColorIndices.find(best[k].index); R_ASSERT(CI!=m_ColorIndices.end());
        U8Vec elem; elem.resize(CI->second.size());
        for (U8It b_it=elem.begin(); b_it!=elem.end(); b_it++) *b_it=u8(b_it-elem.begin());
//        best_rand A(DetailRandom);
        std::random_shuffle(elem.begin(),elem.end());//,A);
        for (b_it=elem.begin(); b_it!=elem.end(); b_it++){
			bool bNotFound=true;
            slot->w_id	(k, GetObject(CI,*b_it));
            for (u32 j=0; j<k; j++)
                if (slot->r_id(j)==slot->r_id(k)){
                	bNotFound	= false;
                    break;
                }
            if (bNotFound) break;
        }

        slot->color_editor();
        // density
        float f = ((EDetail*)objects[slot->r_id(k)])->m_fDensityFactor;

        slot->palette[k].a0 	= (u16)iFloor(best[k].dens[0]*f*15.f+.5f);
        slot->palette[k].a1 	= (u16)iFloor(best[k].dens[1]*f*15.f+.5f);
        slot->palette[k].a2 	= (u16)iFloor(best[k].dens[2]*f*15.f+.5f);
        slot->palette[k].a3 	= (u16)iFloor(best[k].dens[3]*f*15.f+.5f);
    }

    // определим ID незаполненных слотов как пустышки
    for(k=best.size(); k<4; k++)
        slot->w_id(k,DetailSlot::ID_Empty);
    return true;
}