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")); }
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); } } } }
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); }
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]++; }
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); }
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(); } }
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; }
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); } } }
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); }
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); } } }
void C3DCursor::SetColor(Fcolor& c){ dwColor = c.get(); }
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; } } } }
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; }