Exemplo n.º 1
0
void SCarLight::ParseDefinitions(LPCSTR section)
{

	light_render			= ::Render->light_create();
	light_render->set_type	(IRender_Light::SPOT);
	light_render->set_shadow(true);
	glow_render				= ::Render->glow_create();
	//	lanim					= 0;
	//	time2hide				= 0;

	// set bone id
	IKinematics*			pKinematics=smart_cast<IKinematics*>(m_holder->PCar()->Visual());
	CInifile* ini		=	pKinematics->LL_UserData();
	
	Fcolor					clr;
	clr.set					(ini->r_fcolor(section,"color"));
	//clr.mul_rgb				(torch->spot_brightness);
	//fBrightness				= torch->spot_brightness;
	light_render->set_range	(ini->r_float(section,"range"));
	light_render->set_color	(clr);
	light_render->set_cone	(deg2rad(ini->r_float(section,"cone_angle")));
	light_render->set_texture(ini->r_string(section,"spot_texture"));

	glow_render->set_texture(ini->r_string(section,"glow_texture"));
	glow_render->set_color	(clr);
	glow_render->set_radius	(ini->r_float(section,"glow_radius"));
	
	bone_id	= pKinematics->LL_BoneID(ini->r_string(section,"bone"));
	glow_render ->set_active(false);
	light_render->set_active(false);
	pKinematics->LL_SetBoneVisible(bone_id,FALSE,TRUE);

	//lanim					= LALib.FindItem(ini->r_string(section,"animator"));
	
}
Exemplo n.º 2
0
void CHangingLamp::UpdateCL	()
{
	inherited::UpdateCL		();

	if(m_pPhysicsShell)
		m_pPhysicsShell->InterpolateGlobalTransform(&XFORM());

	if (Alive() && light_render->get_active()){
		if(Visual())	PKinematics(Visual())->CalculateBones();

		// update T&R from light (main) bone
		Fmatrix xf;
		if (light_bone!=BI_NONE){
			Fmatrix& M = smart_cast<CKinematics*>(Visual())->LL_GetTransform(light_bone);
			xf.mul		(XFORM(),M);
			VERIFY(!fis_zero(DET(xf)));
		}else{
			xf.set		(XFORM());
		}
		light_render->set_rotation	(xf.k,xf.i);
		light_render->set_position	(xf.c);
		if (glow_render)glow_render->set_position	(xf.c);

		// update T&R from ambient bone
		if (light_ambient){	
			if (ambient_bone!=light_bone){
				if (ambient_bone!=BI_NONE){
					Fmatrix& M = smart_cast<CKinematics*>(Visual())->LL_GetTransform(ambient_bone);
					xf.mul		(XFORM(),M);
					VERIFY(!fis_zero(DET(xf)));
				}else{
					xf.set		(XFORM());
				}
			}
			light_ambient->set_rotation	(xf.k,xf.i);
			light_ambient->set_position	(xf.c);
		}
		
		if (lanim){
			int frame;
			u32 clr					= lanim->CalculateBGR(Device.fTimeGlobal,frame); // возвращает в формате BGR
			Fcolor					fclr;
			fclr.set				((float)color_get_B(clr),(float)color_get_G(clr),(float)color_get_R(clr),1.f);
			fclr.mul_rgb			(fBrightness/255.f);
			light_render->set_color	(fclr);
			if (glow_render)		glow_render->set_color	(fclr);
			if (light_ambient) {
				fclr.mul_rgb		(ambient_power);
				light_ambient->set_color(fclr);
			}
		}
	}
}
Exemplo n.º 3
0
void CDrawUtilities::DrawRomboid(const Fvector& p, float r, u32 c)
{
static const WORD IL[24]={0,2, 2,5, 0,5, 3,5, 3,0, 4,3, 4,0, 4,2, 1,2, 1,5, 1,3, 1,4};
static const WORD IT[24]={2,4,0, 4,3,0, 3,5,0, 5,2,0, 4,2,1, 2,5,1, 5,3,1, 3,4,1};
	u32			vBase,iBase;

    Fcolor C;
    C.set			(c);
    C.mul_rgb		(0.75);
    u32 c1 =		C.get();

    int k;
    FVF::L*	pv;
    WORD* i;
	_VertexStream*	Stream	= &RCache.Vertex;
	_IndexStream*	StreamI	= &RCache.Index;

	// fill VB
	pv	 			= (FVF::L*)Stream->Lock(6,vs_L->vb_stride,vBase);
    pv->set			(p.x,	p.y+r,	p.z,	c1); pv++;
    pv->set			(p.x,	p.y-r,	p.z,	c1); pv++;
    pv->set			(p.x,	p.y,	p.z-r,	c1); pv++;
    pv->set			(p.x,	p.y,	p.z+r,	c1); pv++;
    pv->set			(p.x-r,	p.y,	p.z,	c1); pv++;
    pv->set			(p.x+r,	p.y,	p.z,	c1); pv++;
	Stream->Unlock	(6,vs_L->vb_stride);

    i 				= StreamI->Lock(24,iBase);
    for (k=0; k<24; k++,i++) *i=IT[k];
    StreamI->Unlock(24);

	// and Render it as triangle list
	DU_DRAW_DIP		(D3DPT_TRIANGLELIST,vs_L,vBase,0,6, iBase,12);

    // draw lines
	pv	 			= (FVF::L*)Stream->Lock(6,vs_L->vb_stride,vBase);
    pv->set			(p.x,	p.y+r,	p.z,	c); pv++;
    pv->set			(p.x,	p.y-r,	p.z,	c); pv++;
    pv->set			(p.x,	p.y,	p.z-r,	c); pv++;
    pv->set			(p.x,	p.y,	p.z+r,	c); pv++;
    pv->set			(p.x-r,	p.y,	p.z,	c); pv++;
    pv->set			(p.x+r,	p.y,	p.z,	c); pv++;
	Stream->Unlock	(6,vs_L->vb_stride);

    i 				= StreamI->Lock(24,iBase);
    for (k=0; k<24; k++,i++) *i=IL[k];
    StreamI->Unlock	(24);

	DU_DRAW_DIP		(D3DPT_LINELIST,vs_L,vBase,0,6, iBase,12);
}
Exemplo n.º 4
0
void EDetailManager::CalcClosestCount(int part, const Fcolor& C, SIndexDistVec& best){
    float dist = flt_max;
    Fcolor src;
    float inv_a = 1-C.a;
    int idx = -1;

    for (u32 k=0; k<best.size(); k++){
		src.set(best[k].index);
        float d = inv_a+sqrtf((C.r-src.r)*(C.r-src.r)+(C.g-src.g)*(C.g-src.g)+(C.b-src.b)*(C.b-src.b));
        if (d<dist){
        	dist 	= d;
            idx 	= k;
        }
    }
    if (idx>=0) best[idx].cnt[part]++;
}
Exemplo n.º 5
0
void CCustomZone::UpdateIdleLight	()
{
	if(!m_pIdleLight || !m_pIdleLight->get_active())
		return;


	VERIFY(m_pIdleLAnim);

	int frame = 0;
	u32 clr					= m_pIdleLAnim->CalculateBGR(Device.fTimeGlobal,frame); // возвращает в формате BGR
	Fcolor					fclr;
	fclr.set				((float)color_get_B(clr)/255.f,(float)color_get_G(clr)/255.f,(float)color_get_R(clr)/255.f,1.f);
	
	float range = m_fIdleLightRange + 0.25f*::Random.randF(-1.f,1.f);
	m_pIdleLight->set_range	(range);
	m_pIdleLight->set_color	(fclr);

	Fvector pos		= Position();
	pos.y			+= m_fIdleLightHeight;
	m_pIdleLight->set_position(pos);
}
Exemplo n.º 6
0
void ESceneLightTools::BeforeRender()
{
    if (psDeviceFlags.is(rsLighting)){
        int l_cnt		= 0;
        // set scene lights
        for(ObjectIt _F = m_Objects.begin();_F!=m_Objects.end();_F++){
            CLight* l 		= (CLight*)(*_F);
            l_cnt++;
            if (l->Visible()&&l->m_UseInD3D&&l->m_Flags.is_any(ELight::flAffectDynamic|ELight::flAffectStatic))
                if (::Render->ViewBase.testSphere_dirty(l->PPosition,l->m_Range))
                	AppendFrameLight(l);
        }
    	// set sun
		if (m_Flags.is(flShowSun)){
            Flight L;
            Fvector C;
            if (psDeviceFlags.is(rsEnvironment)){
	            C			= g_pGamePersistent->Environment().CurrentEnv.sun_color;
            }else{
            	C.set		(1.f,1.f,1.f);
            }
            L.direction.setHP(m_SunShadowDir.y,m_SunShadowDir.x);
            L.diffuse.set	(C.x,C.y,C.z,1.f);
            L.ambient.set	(0.f,0.f,0.f,0.f);
            L.specular.set	(C.x,C.y,C.z,1.f);
            L.type			= D3DLIGHT_DIRECTIONAL;
            Device.SetLight	(frame_light.size(),L);
            Device.LightEnable(frame_light.size(),TRUE);
        }
		// ambient
        if (psDeviceFlags.is(rsEnvironment)){
	        Fvector& V		= g_pGamePersistent->Environment().CurrentEnv.ambient;
            Fcolor C;		C.set(V.x,V.y,V.z,1.f);
            Device.SetRS	(D3DRS_AMBIENT,C.get());
        }else				Device.SetRS(D3DRS_AMBIENT,0x00000000);
        
        Device.Statistic->dwTotalLight 	= l_cnt;
        Device.Statistic->dwLightInScene = frame_light.size();
    }
}
Exemplo n.º 7
0
void		CHangingLamp::Synchronize() // alpet: сохранение данных в серверный объект
{
	CSE_ALifeObjectHangingLamp *lamp = get_se_lamp(this);
	if (!lamp) return;
	lamp->position() = XFORM().c;	
	XFORM().getXYZ(lamp->angle());	 
	lamp->brightness = fBrightness;
	lamp->spot_cone_angle = light_render->get_cone();
	lamp->range = light_render->get_range();
	Fcolor clr = light_render->get_color();
	if (fBrightness > 0)
		clr.mul_rgb( 255.f / fBrightness);
	lamp->color = clr.get();

	if (light_ambient)
	{
		lamp->m_ambient_radius = light_ambient->get_range();		
	}	

	if (lanim)
		lamp->color_animator = lanim->cName;
}
Exemplo n.º 8
0
void CHelicopter::UpdateHeliParticles	()
{
	CKinematics* K		= smart_cast<CKinematics*>(Visual());
	m_particleXFORM		= K->LL_GetTransform(m_smoke_bone);
	m_particleXFORM.mulA_43(XFORM());

	if (m_pParticle){
		
		Fvector vel;

		Fvector last_pos = PositionStack.back().vPosition;
		vel.sub(Position(), last_pos);
		vel.mul(5.0f);

		m_pParticle->UpdateParent(m_particleXFORM, vel );
	}
//lighting
	if(m_light_render->get_active()){
		Fmatrix xf;
		Fmatrix& M = K->LL_GetTransform(u16(m_light_bone));
		xf.mul		(XFORM(),M);
		VERIFY(!fis_zero(DET(xf)));

		m_light_render->set_rotation	(xf.k,xf.i);
		m_light_render->set_position	(xf.c);

		if (m_lanim)
		{
			int frame;
			u32 clr					= m_lanim->CalculateBGR(Device.fTimeGlobal,frame); // òþ÷ò¨ð•ðõª ò ¯þ¨üðªõ BGR
			Fcolor					fclr;
			fclr.set				((float)color_get_B(clr),(float)color_get_G(clr),(float)color_get_R(clr),1.f);
			fclr.mul_rgb			(m_light_brightness/255.f);
			m_light_render->set_color	(fclr);
		}

	}
}
Exemplo n.º 9
0
BOOL CHangingLamp::net_Spawn(CSE_Abstract* DC)
{
	CSE_Abstract			*e		= (CSE_Abstract*)(DC);
	CSE_ALifeObjectHangingLamp	*lamp	= smart_cast<CSE_ALifeObjectHangingLamp*>(e);
	R_ASSERT				(lamp);
	inherited::net_Spawn	(DC);
	Fcolor					clr;

	// set bone id
//	CInifile* pUserData		= K->LL_UserData(); 
//	R_ASSERT3				(pUserData,"Empty HangingLamp user data!",lamp->get_visual());
	xr_delete(collidable.model);
	if (Visual()){
		CKinematics* K		= smart_cast<CKinematics*>(Visual());
		R_ASSERT			(Visual()&&smart_cast<CKinematics*>(Visual()));
		light_bone			= K->LL_BoneID	(*lamp->light_main_bone);	VERIFY(light_bone!=BI_NONE);
		ambient_bone		= K->LL_BoneID	(*lamp->light_ambient_bone);VERIFY(ambient_bone!=BI_NONE);
		collidable.model	= xr_new<CCF_Skeleton>				(this);
		// alpet: загрузка иммунитетов из спавн-конфига
		CInifile* ini=K->LL_UserData();
		if(ini && ini->section_exist("immunities"))		CHitImmunity::LoadImmunities("immunities",ini);
	}
	fBrightness				= lamp->brightness;
	clr.set					(lamp->color);						clr.a = 1.f;
	clr.mul_rgb				(fBrightness);

	light_render			= ::Render->light_create();
	light_render->set_shadow(!!lamp->flags.is(CSE_ALifeObjectHangingLamp::flCastShadow));
	light_render->set_type	(lamp->flags.is(CSE_ALifeObjectHangingLamp::flTypeSpot)?IRender_Light::SPOT:IRender_Light::POINT);
	light_render->set_range	(lamp->range);
	light_render->set_color	(clr);
	light_render->set_cone	(lamp->spot_cone_angle);
	light_render->set_texture(*lamp->light_texture);
	light_render->set_virtual_size(lamp->m_virtual_size);

	if (lamp->glow_texture.size())	{
		glow_render				= ::Render->glow_create();
		glow_render->set_texture(*lamp->glow_texture);
		glow_render->set_color	(clr);
		glow_render->set_radius	(lamp->glow_radius);
	}

	if (lamp->flags.is(CSE_ALifeObjectHangingLamp::flPointAmbient)){
		ambient_power			= lamp->m_ambient_power;
		light_ambient			= ::Render->light_create();
		light_ambient->set_type	(IRender_Light::POINT);
		light_ambient->set_shadow(false);
		clr.mul_rgb				(ambient_power);
		light_ambient->set_range(lamp->m_ambient_radius);
		light_ambient->set_color(clr);
		light_ambient->set_texture(*lamp->m_ambient_texture);
		light_ambient->set_virtual_size(lamp->m_virtual_size);
	}

	fHealth					= lamp->m_health;

	lanim					= LALib.FindItem(*lamp->color_animator);

	CPHSkeleton::Spawn(e);
	if (smart_cast<CKinematicsAnimated*>(Visual()))	smart_cast<CKinematicsAnimated*>	(Visual())->PlayCycle("idle");
	if (smart_cast<CKinematics*>(Visual())){
		smart_cast<CKinematics*>			(Visual())->CalculateBones_Invalidate	();
		smart_cast<CKinematics*>			(Visual())->CalculateBones();
		//.intepolate_pos
	}
	if (lamp->flags.is(CSE_ALifeObjectHangingLamp::flPhysic)&&!Visual())
		Msg("! WARNING: lamp, obj name [%s],flag physics set, but has no visual",*cName());
//.	if (lamp->flags.is(CSE_ALifeObjectHangingLamp::flPhysic)&&Visual()&&!guid_physic_bone)	fHealth=0.f;
	if (Alive())			TurnOn	();
	else{
		processing_activate		();	// temporal enable
		TurnOff					();	// -> and here is disable :)
	}
	
	setVisible					((BOOL)!!Visual());
	setEnabled					((BOOL)!!collidable.model);

	return						(TRUE);
}
Exemplo n.º 10
0
void CLensFlare::Render(BOOL bSun, BOOL bFlares, BOOL bGradient)
{
	if (!bRender)		return;
	if(!m_Current)		return;
	VERIFY				(m_Current);

	Fcolor				dwLight;
	Fcolor				color;
	Fvector				vec, vecSx, vecSy;
	Fvector				vecDx, vecDy;

	dwLight.set							( LightColor );
	svector<ref_shader,MAX_Flares>		_2render;

	u32									VS_Offset;
	FVF::LIT *pv						= (FVF::LIT*) RCache.Vertex.Lock(MAX_Flares*4,hGeom.stride(),VS_Offset);

	float 	fDistance		= FAR_DIST*0.75f;

	if (bSun){
    	if (m_Current->m_Flags.is(CLensFlareDescriptor::flSource)){
            vecSx.mul			(vecX, m_Current->m_Source.fRadius*fDistance);
            vecSy.mul			(vecY, m_Current->m_Source.fRadius*fDistance);
            if (m_Current->m_Source.ignore_color) 	color.set(1.f,1.f,1.f,1.f);
            else									color.set(dwLight);
	        color.a				*= m_StateBlend;
            u32 c				= color.get();
            pv->set				(vecLight.x+vecSx.x-vecSy.x, vecLight.y+vecSx.y-vecSy.y, vecLight.z+vecSx.z-vecSy.z, c, 0, 0); pv++;
            pv->set				(vecLight.x+vecSx.x+vecSy.x, vecLight.y+vecSx.y+vecSy.y, vecLight.z+vecSx.z+vecSy.z, c, 0, 1); pv++;
            pv->set				(vecLight.x-vecSx.x-vecSy.x, vecLight.y-vecSx.y-vecSy.y, vecLight.z-vecSx.z-vecSy.z, c, 1, 0); pv++;
            pv->set				(vecLight.x-vecSx.x+vecSy.x, vecLight.y-vecSx.y+vecSy.y, vecLight.z-vecSx.z+vecSy.z, c, 1, 1); pv++;
            _2render.push_back	(m_Current->m_Source.hShader);
        }
	}
	if (fBlend>=EPS_L)
	{
		if(bFlares){
			vecDx.normalize		(vecAxis);
			vecDy.crossproduct	(vecDx, vecDir);
	    	if (m_Current->m_Flags.is(CLensFlareDescriptor::flFlare)){
                for (CLensFlareDescriptor::FlareIt it=m_Current->m_Flares.begin(); it!=m_Current->m_Flares.end(); it++){
                    CLensFlareDescriptor::SFlare&	F = *it;
                    vec.mul				(vecAxis, F.fPosition);
                    vec.add				(vecCenter);
                    vecSx.mul			(vecDx, F.fRadius*fDistance);
                    vecSy.mul			(vecDy, F.fRadius*fDistance);
                    float    cl			= F.fOpacity * fBlend * m_StateBlend;
                    color.set			( dwLight );
                    color.mul_rgba		( cl );
                    u32 c				= color.get();
                    pv->set				(vec.x+vecSx.x-vecSy.x, vec.y+vecSx.y-vecSy.y, vec.z+vecSx.z-vecSy.z, c, 0, 0); pv++;
                    pv->set				(vec.x+vecSx.x+vecSy.x, vec.y+vecSx.y+vecSy.y, vec.z+vecSx.z+vecSy.z, c, 0, 1); pv++;
                    pv->set				(vec.x-vecSx.x-vecSy.x, vec.y-vecSx.y-vecSy.y, vec.z-vecSx.z-vecSy.z, c, 1, 0); pv++;
                    pv->set				(vec.x-vecSx.x+vecSy.x, vec.y-vecSx.y+vecSy.y, vec.z-vecSx.z+vecSy.z, c, 1, 1); pv++;
                    _2render.push_back	(it->hShader);
                }
            }
		}
		// gradient
		if (bGradient&&(fGradientValue>=EPS_L)){
            if (m_Current->m_Flags.is(CLensFlareDescriptor::flGradient)){
                vecSx.mul			(vecX, m_Current->m_Gradient.fRadius*fGradientValue*fDistance);
                vecSy.mul			(vecY, m_Current->m_Gradient.fRadius*fGradientValue*fDistance);

                color.set			( dwLight );
                color.mul_rgba		( fGradientValue*m_StateBlend );

                u32 c				= color.get	();
                pv->set				(vecLight.x+vecSx.x-vecSy.x, vecLight.y+vecSx.y-vecSy.y, vecLight.z+vecSx.z-vecSy.z, c, 0, 0); pv++;
                pv->set				(vecLight.x+vecSx.x+vecSy.x, vecLight.y+vecSx.y+vecSy.y, vecLight.z+vecSx.z+vecSy.z, c, 0, 1); pv++;
                pv->set				(vecLight.x-vecSx.x-vecSy.x, vecLight.y-vecSx.y-vecSy.y, vecLight.z-vecSx.z-vecSy.z, c, 1, 0); pv++;
                pv->set				(vecLight.x-vecSx.x+vecSy.x, vecLight.y-vecSx.y+vecSy.y, vecLight.z-vecSx.z+vecSy.z, c, 1, 1); pv++;
                _2render.push_back	(m_Current->m_Gradient.hShader);
            }
		}
	}
	RCache.Vertex.Unlock	(_2render.size()*4,hGeom.stride());

	RCache.set_xform_world	(Fidentity);
	RCache.set_Geometry		(hGeom);
	for (u32 i=0; i<_2render.size(); i++)
	{
    	if (_2render[i])
		{
			u32						vBase	= i*4+VS_Offset;
			RCache.set_Shader		(_2render[i]);
			RCache.Render			(D3DPT_TRIANGLELIST,vBase, 0,4,0,2);
	    }
	}
}
Exemplo n.º 11
0
void C3DCursor::SetColor(Fcolor& c){
	dwColor = c.get();
}
Exemplo n.º 12
0
void EDetailManager::FindClosestIndex(const Fcolor& C, SIndexDistVec& best)
{
	u32 index;
    float dist = flt_max;
    Fcolor src;
    float inv_a = 1-C.a;
    bool bRes=false;
    ColorIndexPairIt S = m_ColorIndices.begin();
    ColorIndexPairIt E = m_ColorIndices.end();
    ColorIndexPairIt it= S;
	for(; it!=E; it++){
		src.set(it->first);
        float d = inv_a+sqrtf((C.r-src.r)*(C.r-src.r)+(C.g-src.g)*(C.g-src.g)+(C.b-src.b)*(C.b-src.b));
        if (d<dist){
        	dist 	= d;
            index 	= it->first;
            bRes	= true;
        }
    }

    if (bRes){
        if (best.size()<4){
            bool bFound=false;
            for (u32 k=0; k<best.size(); k++){
                if (best[k].index==index){
                	if(dist<best[k].dist){
	                    best[k].dist 	= dist;
    	                best[k].index	= index;
                    }
                    bFound = true;
                    break;
                }
            }
            if (!bFound){
                best.inc();
                best[best.size()-1].dist = dist;
                best[best.size()-1].index= index;
            }
        }else{
            int i=-1;
            float dd=flt_max;
            bool bFound=false;
            for (int k=0; k<4; k++){
                float d = dist-best[k].dist;
                if ((d<0)&&(d<dd)){ i=k; dd=d;}
                if (best[k].index==index){
                	if(dist<best[k].dist){
	                    best[k].dist 	= dist;
    	                best[k].index    = index;
                    }
                    bFound = true;
                    break;
                }
            }
            if (!bFound&&(i>=0)){
                best[i].dist 	= dist;
                best[i].index	= index;
            }
        }
    }
}
Exemplo n.º 13
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;
}