From 96ea03d0a0c639dbf56bdcc1dbcc42eaf9d9b00d Mon Sep 17 00:00:00 2001 From: shenlei Date: Mon, 28 Sep 2026 12:59:31 +0900 Subject: [PATCH] port EterLib/GrpLightManager.cpp verbatim, initialise CLightManager (unit B) Replaces the platform_stub skeleton with the 40250 source and mirrors m_LightManager.Initialize() from 40250 PythonApplication.cpp:1263. Co-Authored-By: Claude Opus 5.5 --- audit/history.jsonl | 1 + .../port-map/EterLib/GrpLightManager.cpp.json | 196 ++++++++++ .../UserInterface/PythonApplication.cpp.json | 2 +- .../src/platform/EterLib/GrpLightManager.cpp | 171 --------- .../UserInterface/PythonApplication.cpp | 4 + .../src/port/EterLib/GrpLightManager.cpp | 345 ++++++++++++++++++ 6 files changed, 547 insertions(+), 172 deletions(-) create mode 100644 audit/port-map/EterLib/GrpLightManager.cpp.json delete mode 100644 extension/src/platform/EterLib/GrpLightManager.cpp create mode 100644 extension/src/port/EterLib/GrpLightManager.cpp diff --git a/audit/history.jsonl b/audit/history.jsonl index 3840ad99..9d425f6c 100644 --- a/audit/history.jsonl +++ b/audit/history.jsonl @@ -558,3 +558,4 @@ {"date": "2026-09-28T01:31:59+00:00", "unit": "GameLib/MapOutdoorRenderHTP.cpp + GameLib/MapOutdoorCharacterShadow.cpp", "action": "native 40250 render parity: terrain near/mid/far LOD/fog/splat cap, character shadow RTT CPU raster, per-draw depth/sampler states and two-light fixed-function shading", "evidence": "mt_native_render fake-server game 90 frames; 178 3D draws; shadow mem texture 205 nonwhite pixels; matched Windows screenshot pending"} {"date": "2026-09-28T01:35:06+00:00", "unit": "GameLib/MapOutdoorRenderHTP.cpp", "action": "match 40250 lighting state in terrain splat passes: unlit base textures, temporary lit shadow pass, white fog color only for shadow pass", "evidence": "reference MapOutdoorRenderHTP.cpp non-WORLD_EDITOR branch; native fake-server scene rerun pending"} {"date": "2026-09-28T03:54:13+00:00", "unit": "EterLib/GrpScreen.cpp + native D3D8 fixed-function emulation (RecordingDevice / native_render)", "action": "unit A: D3D8 texcoord generation + D3DTS_TEXTUREn in shader (CPU uv baking removed), 8-light D3D lighting (no attenuation clamp, spot theta/2 phi/2, emissive source, NORMALIZENORMALS, inverse-transpose normals), 8-bit alpha test, clears in draw order, dynamic D3D viewport + MinZ/MaxZ, black back-buffer clear, white default diffuse, alpha blend mirrors colour factors; removed sphere-map and multiplicative-shadow hacks; CScreen ms_clearDepth/ms_diffuseColor initialisers fixed to 40250 values; capture v8; --screenshot-out readback", "evidence": "ctest 35/35 (login_live excluded); mt_native_render fake-server 240/900-frame screenshots vs baseline: game frame mean abs diff 0.55/255, char select model now placed by introselect.py grp.SetViewport(270/w,...); Windows reference frame pending (NEEDS_LIVE)"} +{"date": "2026-09-28T03:59:30+00:00", "unit": "EterLib/GrpLightManager.cpp", "action": "unit B: platform stub removed, 40250 GrpLightManager.cpp copied verbatim into port/ (port_copy.py); CPythonApplication::Create now calls m_LightManager.Initialize() (40250 :1263) so light IDs start at skip index 1; 40250 never calls FlushLight/RestoreLight, so no device-light change", "evidence": "ctest 35/35 (login_live excluded); fake-server frame 900 vs baseline mean abs diff 0.21/255"} diff --git a/audit/port-map/EterLib/GrpLightManager.cpp.json b/audit/port-map/EterLib/GrpLightManager.cpp.json new file mode 100644 index 00000000..9f56b70f --- /dev/null +++ b/audit/port-map/EterLib/GrpLightManager.cpp.json @@ -0,0 +1,196 @@ +{ + "reference": "EterLib/GrpLightManager.cpp", + "reference_sha256": "673be49eac112ebf7650489db33a185dfbb7215b7b0fe7626f2302b422dc8261", + "priority": "P4", + "contracts": [], + "functions": { + "CLightManager::CLightManager": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::CLightManager" + ] + }, + "CLightManager::~CLightManager": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::~CLightManager" + ] + }, + "CLightManager::Destroy": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::Destroy" + ] + }, + "CLightManager::Initialize": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::Initialize" + ] + }, + "CLightManager::RegisterLight": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::RegisterLight" + ] + }, + "CLightManager::DeleteLight": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::DeleteLight" + ] + }, + "CLightManager::GetLight": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::GetLight" + ] + }, + "CLightManager::SetCenterPosition": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::SetCenterPosition" + ] + }, + "CLightManager::SetLimitLightCount": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::SetLimitLightCount" + ] + }, + "CLightManager::SetSkipIndex": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::SetSkipIndex" + ] + }, + "CLightManager::FlushLight": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::FlushLight" + ], + "note": "40250 has no caller of FlushLight/RestoreLight; effect lights (SimpleLightInstance) are registered but never sent to the device in 40250 either" + }, + "CLightManager::RestoreLight": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::RestoreLight" + ] + }, + "CLightManager::NewLightID": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::NewLightID" + ] + }, + "CLightManager::ReleaseLightID": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::ReleaseLightID" + ] + }, + "CLightManager::Update": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLightManager::Update" + ] + }, + "CLight::CLight": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::CLight" + ] + }, + "CLight::~CLight": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::~CLight" + ] + }, + "CLight::Initialize": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::Initialize" + ] + }, + "CLight::Clear": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::Clear" + ] + }, + "CLight::SetDeviceLight": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::SetDeviceLight" + ], + "note": "m_isEdited is never cleared in 40250; kept" + }, + "CLight::SetParameter": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::SetParameter" + ] + }, + "CLight::SetDiffuseColor": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::SetDiffuseColor" + ] + }, + "CLight::SetAmbientColor": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::SetAmbientColor" + ] + }, + "CLight::SetRange": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::SetRange" + ] + }, + "CLight::GetPosition": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::GetPosition" + ] + }, + "CLight::SetPosition": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::SetPosition" + ] + }, + "CLight::SetDistance": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::SetDistance" + ] + }, + "CLight::BlendDiffuseColor": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::BlendDiffuseColor" + ] + }, + "CLight::BlendAmbientColor": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::BlendAmbientColor" + ] + }, + "CLight::BlendRange": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::BlendRange" + ] + }, + "CLight::Update": { + "status": "PORTED", + "impl": [ + "extension/src/port/EterLib/GrpLightManager.cpp:CLight::Update" + ] + } + } +} diff --git a/audit/port-map/UserInterface/PythonApplication.cpp.json b/audit/port-map/UserInterface/PythonApplication.cpp.json index 02712977..5f9a66a4 100644 --- a/audit/port-map/UserInterface/PythonApplication.cpp.json +++ b/audit/port-map/UserInterface/PythonApplication.cpp.json @@ -157,7 +157,7 @@ "impl": [ "extension/src/platform/UserInterface/PythonApplication.cpp:CPythonApplication::Create" ], - "note": "40250 CPythonApplication lifecycle and state adapted for platform host and singletons", + "note": "40250 CPythonApplication lifecycle and state adapted for platform host and singletons; m_LightManager.Initialize() (40250 :1263) now called; Destroy() still empty (m_LightManager.Destroy at 40250 :1418 not yet mirrored)", "test": "extension/tests/port_login_flow_test.cpp" }, "CPythonApplication::SetGlobalCenterPosition": { diff --git a/extension/src/platform/EterLib/GrpLightManager.cpp b/extension/src/platform/EterLib/GrpLightManager.cpp deleted file mode 100644 index 92b99e0d..00000000 --- a/extension/src/platform/EterLib/GrpLightManager.cpp +++ /dev/null @@ -1,171 +0,0 @@ -// Platform skeleton for EterLib/GrpLightManager.h (40250 EterLib/GrpLightManager.cpp), generated by platform_stub.py. -// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation. -#include "EterLib/StdAfx.h" -#include "EterLib/GrpLightManager.h" - -#include "../PlatformStub.h" - -auto CLightBase::SetCurrentTime() -> void -{ - MT_PLATFORM_STUB(); -} - -decltype(CLightBase::ms_fCurTime) CLightBase::ms_fCurTime{}; - -CLight::CLight() -{ - MT_PLATFORM_STUB(); -} - -CLight::~CLight() -{ - MT_PLATFORM_STUB(); -} - -auto CLight::Initialize() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLight::Clear() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLight::Update() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLight::SetParameter(TLightID, const D3DLIGHT8 &) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLight::SetDistance(float) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLight::SetDeviceLight(BOOL) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLight::SetDiffuseColor(float, float, float, float) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLight::SetAmbientColor(float, float, float, float) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLight::SetRange(float) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLight::SetPosition(float, float, float) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLight::GetPosition() const -> const D3DVECTOR & -{ - MT_PLATFORM_STUB(); - return mt_platform_stub_return(); -} - -auto CLight::BlendDiffuseColor(const D3DXCOLOR &, float, float) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLight::BlendAmbientColor(const D3DXCOLOR &, float, float) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLight::BlendRange(float, float, float) -> void -{ - MT_PLATFORM_STUB(); -} - -CLightManager::CLightManager() -{ - MT_PLATFORM_STUB(); -} - -CLightManager::~CLightManager() -{ - MT_PLATFORM_STUB(); -} - -auto CLightManager::Destroy() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLightManager::Initialize() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLightManager::Update() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLightManager::FlushLight() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLightManager::RestoreLight() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLightManager::RegisterLight(ELightType, TLightID *, D3DLIGHT8 &) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLightManager::GetLight(TLightID) -> CLight * -{ - MT_PLATFORM_STUB(); - return mt_platform_stub_return(); -} - -auto CLightManager::DeleteLight(TLightID) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLightManager::SetCenterPosition(const D3DXVECTOR3 &) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLightManager::SetLimitLightCount(DWORD) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLightManager::SetSkipIndex(DWORD) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CLightManager::NewLightID() -> TLightID -{ - MT_PLATFORM_STUB(); - return mt_platform_stub_return(); -} - -auto CLightManager::ReleaseLightID(TLightID) -> void -{ - MT_PLATFORM_STUB(); -} diff --git a/extension/src/platform/UserInterface/PythonApplication.cpp b/extension/src/platform/UserInterface/PythonApplication.cpp index 176d8cea..071931ee 100644 --- a/extension/src/platform/UserInterface/PythonApplication.cpp +++ b/extension/src/platform/UserInterface/PythonApplication.cpp @@ -136,6 +136,10 @@ bool CPythonApplication::Create(PyObject*, const char*, int, int, int) // 40250 PythonApplication.cpp:1260. CPythonTextTail::Instance().Initialize(); + // 40250 PythonApplication.cpp:1262-1263. + // Light Manager + m_LightManager.Initialize(); + if (IsNativeTerrainRenderEnabled()) { const bool use_hardware_cursor = PythonBoot::HostHardwareCursorEnabled(); diff --git a/extension/src/port/EterLib/GrpLightManager.cpp b/extension/src/port/EterLib/GrpLightManager.cpp new file mode 100644 index 00000000..b9d1f8e8 --- /dev/null +++ b/extension/src/port/EterLib/GrpLightManager.cpp @@ -0,0 +1,345 @@ +#include "StdAfx.h" +#include +#include "../EterBase/Timer.h" + +#include "GrpLightManager.h" +#include "StateManager.h" + +float CLightBase::ms_fCurTime = 0.0f; + +CLightManager::CLightManager() +{ + m_v3CenterPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + m_dwLimitLightCount = LIGHT_LIMIT_DEFAULT; +} + +CLightManager::~CLightManager() +{ +} + +void CLightManager::Destroy() +{ + m_LightPool.Destroy(); +} + +void CLightManager::Initialize() +{ + SetSkipIndex(1); + + m_NonUsingLightIDDeque.clear(); + + m_LightMap.clear(); + m_LightPool.FreeAll(); +} + +void CLightManager::RegisterLight(ELightType /*LightType*/, TLightID * poutLightID, D3DLIGHT8 & LightData) +{ + CLight * pLight = m_LightPool.Alloc(); + TLightID ID = NewLightID(); + pLight->SetParameter(ID, LightData); + m_LightMap[ID] = pLight; + *poutLightID = ID; +} + +void CLightManager::DeleteLight(TLightID LightID) +{ + TLightMap::iterator itor = m_LightMap.find(LightID); + + if (m_LightMap.end() == itor) + { + assert(!"CLightManager::DeleteLight - Failed to find light ID!"); + return; + } + + CLight * pLight = itor->second; + + pLight->Clear(); + m_LightPool.Free(pLight); + + m_LightMap.erase(itor); + + ReleaseLightID(LightID); +} + +CLight * CLightManager::GetLight(TLightID LightID) +{ + TLightMap::iterator itor = m_LightMap.find(LightID); + + if (m_LightMap.end() == itor) + { + assert(!"CLightManager::SetLightData - Failed to find light ID!"); + return NULL; + } + + return itor->second; +} + +void CLightManager::SetCenterPosition(const D3DXVECTOR3 & c_rv3Position) +{ + m_v3CenterPosition = c_rv3Position; +} + +void CLightManager::SetLimitLightCount(DWORD dwLightCount) +{ + m_dwLimitLightCount = dwLightCount; +} + +void CLightManager::SetSkipIndex(DWORD dwSkipIndex) +{ + m_dwSkipIndex = dwSkipIndex; +} + +struct LightComp +{ + bool operator () (const CLight * l, const CLight * r) const + { + return l->GetDistance() < r->GetDistance(); + } +}; + +// NOTE : FlushLight후 렌더링 +// 그 후 반드시 RestoreLight를 해줘야만 한다. +void CLightManager::FlushLight() +{ + Update(); + + m_LightSortVector.clear(); + + // NOTE: Dynamic과 Static을 분리 시키고 CenterPosition이 바뀔때마다 Static만 + // 다시 Flush 하는 식으로 최적화 할 수 있다. - [levites] + + // light들의 거리를 추출해 정렬한다. + TLightMap::iterator itor = m_LightMap.begin(); + + for (; itor != m_LightMap.end(); ++itor) + { + CLight * pLight = itor->second; + + D3DXVECTOR3 v3LightPos(pLight->GetPosition()); + D3DXVECTOR3 v3Distance(v3LightPos - m_v3CenterPosition); + pLight->SetDistance(D3DXVec3Length(&v3Distance)); + m_LightSortVector.push_back(pLight); + } + + // quick sort lights + std::sort(m_LightSortVector.begin(), m_LightSortVector.end(), LightComp()); + + // NOTE - 거리로 정렬된 라이트를 Limit 갯수 만큼 제한해서 켜준다. + STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, TRUE); + + for (DWORD k = 0; k < min(m_dwLimitLightCount, m_LightSortVector.size()); ++k) + { + m_LightSortVector[k]->Update(); + m_LightSortVector[k]->SetDeviceLight(TRUE); + + } +} + +void CLightManager::RestoreLight() +{ + STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING); + + for (DWORD k = 0; k < min(m_dwLimitLightCount, m_LightSortVector.size()); ++k) + m_LightSortVector[k]->SetDeviceLight(FALSE); +} + +TLightID CLightManager::NewLightID() +{ + if (!m_NonUsingLightIDDeque.empty()) + { + TLightID id = m_NonUsingLightIDDeque.back(); + m_NonUsingLightIDDeque.pop_back(); + return (id); + } + + return m_dwSkipIndex + m_LightMap.size(); +} + +void CLightManager::ReleaseLightID(TLightID LightID) +{ + m_NonUsingLightIDDeque.push_back(LightID); +} + +void CLightManager::Update() +{ + //static DWORD s_dwStartTime = ELTimer_GetMSec(); + //ms_fCurTime = float(ELTimer_GetMSec() - s_dwStartTime) / 1000.0f; + ms_fCurTime = CTimer::Instance().GetCurrentSecond(); +} + +////////////////////////////////////////////////////////////////////////// +CLight::CLight() +{ + Initialize(); +} + +CLight::~CLight() +{ + Clear(); +} + +void CLight::Initialize() +{ + m_LightID = 0; + m_isEdited = TRUE; + m_fDistance = 0.0f; + + memset(&m_d3dLight, 0, sizeof(m_d3dLight)); + + m_d3dLight.Type = D3DLIGHT_POINT; + m_d3dLight.Attenuation0 = 0.0f; + m_d3dLight.Attenuation1 = 1.0f; + m_d3dLight.Attenuation2 = 0.0f; +} + +void CLight::Clear() +{ + if (m_LightID) + SetDeviceLight(FALSE); + Initialize(); +} + +void CLight::SetDeviceLight(BOOL bActive) +{ + if (bActive && m_isEdited) + { + if (ms_lpd3dDevice) + ms_lpd3dDevice->SetLight(m_LightID, &m_d3dLight); + } + if (ms_lpd3dDevice) + { + ms_lpd3dDevice->LightEnable(m_LightID, bActive); + } +} + +void CLight::SetParameter(TLightID id, const D3DLIGHT8 & c_rLight) +{ + m_LightID = id; + m_d3dLight = c_rLight; +} + +void CLight::SetDiffuseColor(float fr, float fg, float fb, float fa) +{ + if (m_d3dLight.Diffuse.r == fr + && m_d3dLight.Diffuse.g == fg + && m_d3dLight.Diffuse.b == fb + && m_d3dLight.Diffuse.a == fa + ) + return; + m_d3dLight.Diffuse.r = fr; + m_d3dLight.Diffuse.g = fg; + m_d3dLight.Diffuse.b = fb; + m_d3dLight.Diffuse.a = fa; + m_isEdited = TRUE; +} + +void CLight::SetAmbientColor(float fr, float fg, float fb, float fa) +{ + if (m_d3dLight.Ambient.r == fr + && m_d3dLight.Ambient.g == fg + && m_d3dLight.Ambient.b == fb + && m_d3dLight.Ambient.a == fa + ) + return; + m_d3dLight.Ambient.r = fr; + m_d3dLight.Ambient.g = fg; + m_d3dLight.Ambient.b = fb; + m_d3dLight.Ambient.a = fa; + m_isEdited = TRUE; +} + +void CLight::SetRange(float fRange) +{ + if (m_d3dLight.Range == fRange) + return; + + m_d3dLight.Range = fRange; + m_isEdited = TRUE; +} + +const D3DVECTOR & CLight::GetPosition() const +{ + return m_d3dLight.Position; +} + +void CLight::SetPosition(float fx, float fy, float fz) +{ + if (m_d3dLight.Position.x == fx && m_d3dLight.Position.y == fy && m_d3dLight.Position.z == fz) + return; + + m_d3dLight.Position.x = fx; + m_d3dLight.Position.y = fy; + m_d3dLight.Position.z = fz; + m_isEdited = TRUE; +} + +void CLight::SetDistance(float fDistance) +{ + m_fDistance = fDistance; +} + +void CLight::BlendDiffuseColor(const D3DXCOLOR & c_rColor, float fBlendTime, float fDelayTime) +{ + D3DXCOLOR Color(m_d3dLight.Diffuse); + m_DiffuseColorTransitor.SetTransition(Color, c_rColor, ms_fCurTime + fDelayTime, fBlendTime); +} + +void CLight::BlendAmbientColor(const D3DXCOLOR & c_rColor, float fBlendTime, float fDelayTime) +{ + D3DXCOLOR Color(m_d3dLight.Ambient); + m_AmbientColorTransitor.SetTransition(Color, c_rColor, ms_fCurTime + fDelayTime, fBlendTime); +} + +void CLight::BlendRange(float fRange, float fBlendTime, float fDelayTime) +{ + m_RangeTransitor.SetTransition(m_d3dLight.Range, fRange, ms_fCurTime + fDelayTime, fBlendTime); +} + +void CLight::Update() +{ + if (m_AmbientColorTransitor.isActiveTime(ms_fCurTime)) + { + if (!m_AmbientColorTransitor.isActive()) + { + m_AmbientColorTransitor.SetActive(); + m_AmbientColorTransitor.SetSourceValue(m_d3dLight.Ambient); + } + else + { + D3DXCOLOR Color; + + m_AmbientColorTransitor.GetValue(ms_fCurTime, &Color); + SetAmbientColor(Color.r, Color.g, Color.b, Color.a); + } + } + + if (m_DiffuseColorTransitor.isActiveTime(ms_fCurTime)) + { + if (!m_DiffuseColorTransitor.isActive()) + { + m_DiffuseColorTransitor.SetActive(); + m_DiffuseColorTransitor.SetSourceValue(m_d3dLight.Diffuse); + } + else + { + D3DXCOLOR Color; + m_DiffuseColorTransitor.GetValue(ms_fCurTime, &Color); + SetDiffuseColor(Color.r, Color.g, Color.b, Color.a); + } + } + + if (m_RangeTransitor.isActiveTime(ms_fCurTime)) + { + if (!m_RangeTransitor.isActive()) + { + m_RangeTransitor.SetActive(); + m_RangeTransitor.SetSourceValue(m_d3dLight.Range); + } + else + { + float fRange; + m_RangeTransitor.GetValue(ms_fCurTime, &fRange); + SetRange(fRange); + } + } +}