Exemple #1
0
        /**
         * @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);
        }
Exemple #2
0
        /**
         * @brief if the edge should cast shadow
         */
        virtual public bool ShouldEdgeHasShadow(ShadingBody _shadingBody, int _edge)
        {
            Vector2 startPoint  = _shadingBody.GetVertexInWorld(_edge);
            Vector2 edgeVector2 = _shadingBody.GetVertexInWorld((_edge + 1) % _shadingBody.GetVerticesNumber())
                                  - startPoint;
            Vector3 edgeVector3    = new Vector3(edgeVector2.X, edgeVector2.Y, 0.0f);
            Vector3 normal         = Vector3.Cross(edgeVector3, -Vector3.UnitZ);
            Vector2 lightDirection = GetLightDirection(startPoint);
            Vector2 normal2D       = new Vector2(normal.X, normal.Y);

            return(Vector2.Dot(normal2D, lightDirection) < 0.0f);
        }
Exemple #3
0
        /**
         * @brief render lightmap into m_accumulateLight
         */
        public override void DoRender(int _timeLastFrame)
        {
            // Prepare accumulate
            GraphicsDevice graphicsDevice = Mgr <GraphicsDevice> .Singleton;

            Renderer.SetColorTarget(m_accumulateLight);
            RenderAmbientColor(graphicsDevice);
            Renderer.CancelColorTarget();


            // for each light
            foreach (KeyValuePair <int, Light> keyValue in m_lightDict)
            {
                // TODO: test if the light affects current scene
                // init light map
                Renderer.SetColorTarget(m_lightMap);
                graphicsDevice.Clear(Color.Black);
                // draw light
                // TODO: draw light
                keyValue.Value.Draw(_timeLastFrame);
                // substract shadow
                if (m_light2ShadingBodyDict.ContainsKey(keyValue.Key))
                {
                    foreach (int shadingBodyID in m_light2ShadingBodyDict[keyValue.Key])
                    {
                        ShadingBody shadingBody = m_shadingBodyDict[shadingBodyID];
                        for (int i = 0; i < shadingBody.GetVerticesNumber(); ++i)
                        {
                            int lightShadingBodyEdgeID = GetLightShadowBodyEdgeID(keyValue.Key, shadingBodyID, i);
                            if (m_lightShadowEdgeDict.ContainsKey(lightShadingBodyEdgeID))
                            {
                                m_lightShadowEdgeDict[lightShadingBodyEdgeID].Draw(_timeLastFrame);
                            }
                        }
                    }
                }
                Renderer.CancelColorTarget();
                // add to accumulate
                Renderer.SetColorTarget(m_preAccumulateLight);
                m_accumulateEffect.CurrentTechnique = m_accumulateEffect.Techniques["Main"];
                m_accumulateEffect.Parameters["PreColor"].SetValue((Texture2D)m_accumulateLight);
                m_accumulateEffect.Parameters["LightMap"].SetValue((Texture2D)m_lightMap);
                m_accumulateEffect.CurrentTechnique.Passes["P0"].Apply();
                RenderQuad();
                Renderer.CancelColorTarget();
                RenderTarget2D temp = m_preAccumulateLight;
                m_preAccumulateLight = m_accumulateLight;
                m_accumulateLight    = temp;
            }
        }
Exemple #4
0
        /**
         * @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);
                        }
                    }
                }
            }
        }
Exemple #5
0
        public void RemoveShadingBody(ShadingBody _shadingBody)
        {
            int shadingBoydID = _shadingBody.ID;

            if (m_shadingBodyDict.ContainsKey(shadingBoydID))
            {
                m_shadingBodyDict.Remove(shadingBoydID);
            }
            if (m_shadingBody2LightDict.ContainsKey(shadingBoydID))
            {
                HashSet <int> lights = m_shadingBody2LightDict[shadingBoydID];
                foreach (int lightID in lights)
                {
                    // remove from light2ShadingBody
                    // TODO: compromise
                    if (m_light2ShadingBodyDict.ContainsKey(lightID))
                    {
                        m_light2ShadingBodyDict[lightID].Remove(shadingBoydID);
                    }
                    // remove lightShadow
                    int lightShadingBodyEdgeID = GetLightShadowBodyEdgeID(lightID, shadingBoydID, _shadingBody.GetVerticesNumber());
                    if (m_lightShadowEdgeDict.ContainsKey(lightShadingBodyEdgeID))
                    {
                        m_lightShadowEdgeDict.Remove(lightShadingBodyEdgeID);
                    }
                }
                m_shadingBody2LightDict.Remove(shadingBoydID);
            }
            ReturnID(shadingBoydID, m_freeShadowBodyIDList);
            return;
        }
Exemple #6
0
        public void RemoveLight(Light _light)
        {
            int lightID = _light.ID;

            if (m_lightDict.ContainsKey(lightID))
            {
                m_lightDict.Remove(lightID);
            }
            if (m_light2ShadingBodyDict.ContainsKey(lightID))
            {
                HashSet <int> shadingBodies = m_light2ShadingBodyDict[lightID];
                foreach (int shadingBodyID in shadingBodies)
                {
                    // remove from shadingBody2Light
                    m_shadingBody2LightDict[shadingBodyID].Remove(lightID);
                    // remove lightShadow
                    ShadingBody shadingBody            = m_shadingBodyDict[shadingBodyID];
                    int         lightShadingBodyEdgeID = GetLightShadowBodyEdgeID(lightID, shadingBodyID, shadingBody.GetVerticesNumber());
                    if (m_lightShadowEdgeDict.ContainsKey(lightShadingBodyEdgeID))
                    {
                        m_lightShadowEdgeDict.Remove(lightShadingBodyEdgeID);
                    }
                }
                m_light2ShadingBodyDict.Remove(lightID);
            }
            ReturnID(lightID, m_freeLightIDList);
            return;
        }