/** * 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); } } }
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; } } } } }