Exemplo n.º 1
0
void World::CullLights(VisibleCullResult & result, Camera * cam)
{
    List<Light*>::Iterator whr = mLights.Begin();
    List<Light*>::Iterator end = mLights.End();

    while (whr != end)
    {
        // current it's false
        Light * light = *whr;

        if (!light->IsVisible())
            continue;

        switch (light->GetType())
        {
        case LT_DIRECTIONAL:
            result.lights.PushBack(light);
            break;

        case LT_POINT:
        case LT_SPOT:
        {
            Sphere sph = Sphere(light->GetPosition(), light->GetRange());
            if (cam->IsVisible(sph))
                result.lights.PushBack(light);
        }
        break;
        }

        ++whr;
    }
}
Exemplo n.º 2
0
void World::GetVisibleLights(Node * node, List<Light*> & lights)
{
    profile_code();

    lights.Clear();

    List<Light*>::Iterator iter;
    List<Light*>::Iterator end;

    iter = mLights.Begin();
    end = mLights.End();

    Light * light;

    while (iter != end)
    {
        light = *iter;

        if (light->IsVisible())
        {
            LIGHT_TYPE type = light->GetType();

            if (type == LT_DIRECTIONAL)
            {
                lights.PushBack(light);
            }

            else if (type == LT_POINT)
            {
                const Sphere & sph = node->GetWorldBoundingSphere();
                float len = Math::VecLength(light->GetPosition() - sph.center);
                if (len - sph.radius < light->GetRange())
                    lights.PushBack(light);
            }

            else if (type == LT_SPOT)
            {
                Aabb aabb;
                Vec3 ltf, lbf, rtf, rbf;
                Vec3 ltb, lbb, rtb, rbb;
                Vec3 lp;

                float sq1, sq2, sq3, sq4;
                float sq5, sq6, sq7, sq8;
                float rsq;

                Vec3 d1, d2, d3, d4;
                Vec3 d5, d6, d7, d8;
                Vec3 ld;
                float dt1, dt2, dt3, dt4;
                float dt5, dt6, dt7, dt8;
                float mdt;

                aabb = node->GetWorldAabb();

                ltf = aabb.GetLeftTopFrontPoint();
                lbf = aabb.GetLeftBottomFrontPoint();
                rtf = aabb.GetRightTopFrontPoint();
                rbf = aabb.GetRightBottomFrontPoint();

                ltb = aabb.GetLeftTopBackPoint();
                lbb = aabb.GetLeftBottomBackPoint();
                rtb = aabb.GetRightTopBackPoint();
                rbb = aabb.GetRightBottomBackPoint();

                lp = light->GetPosition();
                rsq = light->GetRange() * light->GetRange();

                sq1 = Math::VecDistanceSq(lp, ltf);
                sq2 = Math::VecDistanceSq(lp, lbf);
                sq3 = Math::VecDistanceSq(lp, rtf);
                sq4 = Math::VecDistanceSq(lp, rbf);
                sq5 = Math::VecDistanceSq(lp, ltb);
                sq6 = Math::VecDistanceSq(lp, lbb);
                sq7 = Math::VecDistanceSq(lp, rtb);
                sq8 = Math::VecDistanceSq(lp, rbb);

                if (sq1 < rsq || sq2 < rsq || sq3 < rsq || sq4 < rsq ||
                        sq5 < rsq || sq6 < rsq || sq7 < rsq || sq8 < rsq)
                {
                    ld = light->GetDirection();
                    mdt = light->GetOuter();

                    d1 = ltf - lp;
                    d2 = lbf - lp;
                    d3 = rtf - lp;
                    d4 = rbf - lp;
                    d5 = ltb - lp;
                    d6 = lbb - lp;
                    d7 = rtb - lp;
                    d8 = rbb - lp;

                    Math::VecNormalize(d1, d1);
                    Math::VecNormalize(d2, d2);
                    Math::VecNormalize(d3, d3);
                    Math::VecNormalize(d4, d4);
                    Math::VecNormalize(d5, d5);
                    Math::VecNormalize(d6, d6);
                    Math::VecNormalize(d7, d7);
                    Math::VecNormalize(d8, d8);

                    dt1 = Math::VecDot(ld, d1);
                    dt2 = Math::VecDot(ld, d2);
                    dt3 = Math::VecDot(ld, d3);
                    dt4 = Math::VecDot(ld, d4);
                    dt5 = Math::VecDot(ld, d5);
                    dt6 = Math::VecDot(ld, d6);
                    dt7 = Math::VecDot(ld, d7);
                    dt8 = Math::VecDot(ld, d8);

                    if (dt1 > mdt || dt2 > mdt || dt3 > mdt || dt4 > mdt ||
                            dt5 > mdt || dt6 > mdt || dt7 > mdt || dt7 > mdt)
                    {
                        lights.PushBack(light);
                    }
                }
            }
        }

        ++iter;
    }
}