/** * @brief update then given LightShadow (create it if the given on is null) * according to the given Light, ShadingBody and Edge */ static public LightShadow UpdateShadow( LightShadow _toBeUpdate, Light _light, ShadingBody _body, int _edgeIndex) { if (_edgeIndex > _body.GetVerticesNumber()) { return(null); } Vector2 startPoint = _body.GetVertexInWorld(_edgeIndex); Vector2 endPoint = _body.GetVertexInWorld((_edgeIndex + 1) % _body.GetVerticesNumber()); Vector2 startTill = startPoint + _light.GetLightDirection(startPoint) * ShadowDistance; Vector2 endTill = endPoint + _light.GetLightDirection(endPoint) * ShadowDistance; // update _toBeUpdate LightShadow shadow = _toBeUpdate; if (shadow == null) { shadow = new LightShadow(); } shadow.m_vertexList[0] = startPoint; shadow.m_vertexList[1] = startTill; shadow.m_vertexList[2] = endTill; shadow.m_vertexList[3] = endPoint; // TODO: not here shadow.UpdateDrawVertex(); return(shadow); }
/** * @brief update lightShadow because the given light has moved * the algorithm check all the shadowBody then update: * 1. m_shadingBody2LightDict * 2. m_light2ShadingBodyDict * 3. m_lightShadwEdgeDict * and it also create and remove LightShadow */ public void UpdateLight(Light _light) { HashSet <int> oldShadowBody; if (m_light2ShadingBodyDict.ContainsKey(_light.ID)) { oldShadowBody = m_light2ShadingBodyDict[_light.ID]; } else { oldShadowBody = new HashSet <int>(); } foreach (KeyValuePair <int, ShadingBody> KeyValuePair in m_shadingBodyDict) { if (_light.IsBodyInLightRange(KeyValuePair.Value.GetVertices(), KeyValuePair.Value.GetTransform2World())) { int edgeNumber = KeyValuePair.Value.GetVerticesNumber(); for (int e = 0; e < edgeNumber; ++e) { int lightShadowBodyEdgeID = GetLightShadowBodyEdgeID(_light.ID, KeyValuePair.Key, e); // if edge under light if (_light.ShouldEdgeHasShadow(KeyValuePair.Value, e)) { if (!m_lightShadowEdgeDict.ContainsKey(lightShadowBodyEdgeID)) { m_lightShadowEdgeDict.Add(lightShadowBodyEdgeID, LightShadow.UpdateShadow(null, _light, KeyValuePair.Value, e)); } else { m_lightShadowEdgeDict[lightShadowBodyEdgeID] = LightShadow.UpdateShadow(m_lightShadowEdgeDict[lightShadowBodyEdgeID], _light, KeyValuePair.Value, e); } m_lightShadowEdgeDict[lightShadowBodyEdgeID].Enable = true; } else { if (m_lightShadowEdgeDict.ContainsKey(lightShadowBodyEdgeID)) { m_lightShadowEdgeDict[lightShadowBodyEdgeID].Enable = false; } } } // update light 2 shadow and shadow 2 light if (!m_light2ShadingBodyDict.ContainsKey(_light.ID)) { m_light2ShadingBodyDict[_light.ID] = new HashSet <int>(); } m_light2ShadingBodyDict[_light.ID].Add(KeyValuePair.Key); if (!m_shadingBody2LightDict.ContainsKey(KeyValuePair.Key)) { m_shadingBody2LightDict[KeyValuePair.Key] = new HashSet <int>(); } m_shadingBody2LightDict[KeyValuePair.Key].Add(_light.ID); } //else else { if (oldShadowBody.Contains(KeyValuePair.Key)) { // remove shadow int edgeNumber = KeyValuePair.Value.GetVerticesNumber(); for (int e = 0; e < edgeNumber; ++e) { int lightShadowBodyEdgeID = GetLightShadowBodyEdgeID(_light.ID, KeyValuePair.Key, e); if (m_lightShadowEdgeDict.ContainsKey(lightShadowBodyEdgeID)) { // TODO: not only disable m_lightShadowEdgeDict[lightShadowBodyEdgeID].Enable = false; } } // update light 2 shadow and shadow 2 light oldShadowBody.Remove(KeyValuePair.Key); if (m_light2ShadingBodyDict.ContainsKey(_light.ID)) { m_light2ShadingBodyDict[_light.ID].Remove(KeyValuePair.Key); } } } } }
/** * @brief update lightShadow because the given shadingbody has moved * the algorithm check all the lights then update: * 1. m_shadingBody2LightDict * 2. m_light2ShadingBodyDict * 3. m_lightShadwEdgeDict * and it also create and remove LightShadow */ public void UpdateShadowBody(ShadingBody _shadowBody) { HashSet <int> oldLight; if (m_shadingBody2LightDict.ContainsKey(_shadowBody.ID)) { oldLight = m_shadingBody2LightDict[_shadowBody.ID]; } else { oldLight = new HashSet <int>(); } foreach (KeyValuePair <int, Light> keyValue in m_lightDict) { // if body in light if (keyValue.Value.IsBodyInLightRange(_shadowBody.GetVertices(), _shadowBody.GetTransform2World())) { // update shadow int edgeNumber = _shadowBody.GetVerticesNumber(); for (int e = 0; e < edgeNumber; ++e) { int lightShadowBodyEdgeID = GetLightShadowBodyEdgeID(keyValue.Key, _shadowBody.ID, e); // if edge under light if (keyValue.Value.ShouldEdgeHasShadow(_shadowBody, e)) { m_lightShadowEdgeDict[lightShadowBodyEdgeID] = LightShadow.UpdateShadow(m_lightShadowEdgeDict[lightShadowBodyEdgeID], keyValue.Value, _shadowBody, e); m_lightShadowEdgeDict[lightShadowBodyEdgeID].Enable = true; } // else else { // TODO: not only disable, but also remove it m_lightShadowEdgeDict[lightShadowBodyEdgeID].Enable = false; } } // update light 2 shadow and shadow 2 light if (!m_light2ShadingBodyDict.ContainsKey(keyValue.Key)) { m_light2ShadingBodyDict[keyValue.Key] = new HashSet <int>(); } m_light2ShadingBodyDict[keyValue.Key].Add(_shadowBody.ID); if (!m_shadingBody2LightDict.ContainsKey(_shadowBody.ID)) { m_shadingBody2LightDict[_shadowBody.ID] = new HashSet <int>(); } m_shadingBody2LightDict[_shadowBody.ID].Add(keyValue.Key); } // else else { // if light in old-light if (oldLight.Contains(keyValue.Key)) { // remove shadow int edgeNumber = _shadowBody.GetVerticesNumber(); for (int e = 0; e < edgeNumber; ++e) { int lightShadowBodyEdgeID = GetLightShadowBodyEdgeID(keyValue.Key, _shadowBody.ID, e); if (m_lightShadowEdgeDict.ContainsKey(lightShadowBodyEdgeID)) { // TODO: not only disable m_lightShadowEdgeDict[lightShadowBodyEdgeID].Enable = false; } } // update light2 2 shadow and shadow 2 light oldLight.Remove(keyValue.Key); if (m_light2ShadingBodyDict.ContainsKey(keyValue.Key)) { m_light2ShadingBodyDict[keyValue.Key].Remove(_shadowBody.ID); } } } } }