Esempio n. 1
0
/**
 * Interpret vlights from glowing planes at the @a origin in the specfified
 * @a bspleaf and add them to the identified list.
 */
static void lightWithPlaneGlows(Vector3d const &origin, BspLeaf &bspLeaf, uint listIdx)
{
    SectorCluster &cluster = bspLeaf.cluster();
    for(int i = 0; i < cluster.sector().planeCount(); ++i)
    {
        Plane &plane     = cluster.visPlane(i);
        Surface &surface = plane.surface();

        // Glowing at this moment?
        Vector3f glowColor;
        float intensity = surface.glow(glowColor);
        if(intensity < .05f)
            continue;

        coord_t glowHeight = Rend_PlaneGlowHeight(intensity);
        if(glowHeight < 2)
            continue; // Not too small!

        // In front of the plane?
        Vector3d pointOnPlane = Vector3d(cluster.center(), plane.heightSmoothed());
        double dist = (origin - pointOnPlane).dot(surface.normal());
        if(dist < 0)
            continue;

        intensity *= 1 - dist / glowHeight;
        if(intensity < .05f)
            continue;

        Vector3f color = Rend_LuminousColor(glowColor, intensity);

        if(color != Vector3f(0, 0, 0))
        {
            ListNode *node = newVLight();
            VectorLight *vlight = &node->vlight;

            vlight->direction  = Vector3f(surface.normal().x, surface.normal().y, -surface.normal().z);
            vlight->color      = color;
            vlight->affectedByAmbient = true;
            vlight->approxDist = dist;
            vlight->lightSide  = 1;
            vlight->darkSide   = 0;
            vlight->offset     = .3f;

            linkNodeInList(node, listIdx);
        }
    }
}
Esempio n. 2
0
    void addNeighborIntercepts(coord_t bottom, coord_t top)
    {
        ClockDirection const direction = edge? Clockwise : Anticlockwise;

        HEdge *hedge = wallHEdge;
        while((hedge = &SectorClusterCirculator::findBackNeighbor(*hedge, direction)) != wallHEdge)
        {
            // Stop if there is no back cluster.
            BspLeaf *backLeaf = hedge->hasFace()? &hedge->face().mapElementAs<BspLeaf>() : 0;
            if(!backLeaf || !backLeaf->hasCluster())
                break;

            SectorCluster &cluster = backLeaf->cluster();
            if(cluster.hasWorldVolume())
            {
                for(int i = 0; i < cluster.visPlaneCount(); ++i)
                {
                    Plane const &plane = cluster.visPlane(i);

                    if(plane.heightSmoothed() > bottom && plane.heightSmoothed() < top)
                    {
                        ddouble distance = distanceTo(plane.heightSmoothed());
                        if(!haveEvent(distance))
                        {
                            createEvent(distance);

                            // Have we reached the div limit?
                            if(interceptCount() == WALLEDGE_MAX_INTERCEPTS)
                                return;
                        }
                    }

                    // Clip a range bound to this height?
                    if(plane.isSectorFloor() && plane.heightSmoothed() > bottom)
                        bottom = plane.heightSmoothed();
                    else if(plane.isSectorCeiling() && plane.heightSmoothed() < top)
                        top = plane.heightSmoothed();

                    // All clipped away?
                    if(bottom >= top)
                        return;
                }
            }
            else
            {
                /*
                 * A neighbor with zero volume is a special case -- the potential
                 * division is at the height of the back ceiling. This is because
                 * elsewhere we automatically fix the case of a floor above a
                 * ceiling by lowering the floor.
                 */
                coord_t z = cluster.visCeiling().heightSmoothed();

                if(z > bottom && z < top)
                {
                    ddouble distance = distanceTo(z);
                    if(!haveEvent(distance))
                    {
                        createEvent(distance);
                        // All clipped away.
                        return;
                    }
                }
            }
        }
    }