Exemplo n.º 1
0
void radiosity_lightmap::generate(world_lightmap_access& data,
                                       const chunk_coordinates& pos,
                                       const surface& s, lightmap_hr &lightchunk,
                                       unsigned int phase) const
{
    std::array<float, 6> irr_sun, irr_ambient, irr_artificial;
    vector half {0.5f, 0.5f, 0.5f};
    auto lmi = std::begin(lightchunk);
    for (const faces& f : s)
    {
        fill(irr_sun, 0.f);
        fill(irr_ambient, 0.f);
        fill(irr_artificial, 0.f);

        auto surr (surroundings(f.pos, phase + 1));
        for (auto sp : surr)
        {
            if (sp == f.pos)
                continue;

            auto found (find(s, sp));
            if (found == s.end())
                continue;

            auto& other (*found);
            for (int i = 0; i < 6; ++i)
            {
                if (!f[i])
                    continue;

                vector this_face (half + f.pos + vector(dir_vector[i]) * 0.52f);
                for (int j = 0; j < 6; ++j)
                {
                    if (i == j || !other[j])
                        continue;

                    vector that_face (half + other.pos + vector(dir_vector[j])* 0.52f);
                    vector conn (that_face - this_face);
                    vector norm_conn (normalize(conn));
                    float dp1 (dot_prod<vector>(dir_vector[j], -norm_conn));
                    if (dp1 <= 0)
                        continue;

                    float dp2 = dot_prod<vector>(dir_vector[i], norm_conn);
                    if (dp2 <= 0)
                        continue;

                    float intensity = dp1 * dp2 / squared_length(conn);

                    auto dist = std::distance(std::begin(s), found);
                    auto& olm = lightchunk.data[dist];

                    irr_sun[i] += olm.sunlight * intensity;
                    irr_ambient[i] += olm.ambient * intensity;
                    irr_artificial[i] += olm.artificial * intensity;
                }
            }
        }

        for (int i (0); i < 6; ++i)
        {
            if (!f[i])
                continue;

            lmi->r_sunlight = irr_sun[i] * 255.f + 0.49f;
            lmi->r_ambient = irr_ambient[i] * 255.f + 0.49f;
            lmi->r_artificial = irr_artificial[i] * 255.f + 0.49f;

            ++lmi;
        }
    }
}