Ejemplo n.º 1
0
void ADynamicLight::CollectWithinRadius(subsector_t *subSec, float radius)
{
	if (!subSec) return;

	subSec->validcount = ::validcount;

	touching_subsectors = AddLightNode(&subSec->lighthead, subSec, this, touching_subsectors);
	if (subSec->sector->validcount != ::validcount)
	{
		touching_sector = AddLightNode(&subSec->render_sector->lighthead, subSec->sector, this, touching_sector);
		subSec->sector->validcount = ::validcount;
	}

	for (unsigned int i = 0; i < subSec->numlines; i++)
	{
		seg_t * seg = subSec->firstline + i;

		if (seg->sidedef && seg->linedef && seg->linedef->validcount!=::validcount)
		{
			// light is in front of the seg
			if (DMulScale32 (y-seg->v1->y, seg->v2->x-seg->v1->x, seg->v1->x-x, seg->v2->y-seg->v1->y) <=0)
			{
				seg->linedef->validcount=validcount;
				touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides);
			}
		}

		seg_t *partner = seg->PartnerSeg;
		if (partner)
		{
			subsector_t *sub = partner->Subsector;
			if (sub != NULL && sub->validcount!=::validcount)
			{
				// check distance from x/y to seg and if within radius add opposing subsector (lather/rinse/repeat)
				if (DistToSeg(seg) <= radius)
				{
					CollectWithinRadius(sub, radius);
				}
			}
		}
	}
}
Ejemplo n.º 2
0
void ADynamicLight::CollectWithinRadius(const DVector3 &pos, subsector_t *subSec, float radius)
{
	if (!subSec) return;

	subSec->validcount = ::validcount;

	touching_subsectors = AddLightNode(&subSec->lighthead, subSec, this, touching_subsectors);
	if (subSec->sector->validcount != ::validcount)
	{
		touching_sector = AddLightNode(&subSec->render_sector->lighthead, subSec->sector, this, touching_sector);
		subSec->sector->validcount = ::validcount;
	}

	for (unsigned int i = 0; i < subSec->numlines; i++)
	{
		seg_t * seg = subSec->firstline + i;

		// check distance from x/y to seg and if within radius add this seg and, if present the opposing subsector (lather/rinse/repeat)
		// If out of range we do not need to bother with this seg.
		if (DistToSeg(pos, seg) <= radius)
		{
			if (seg->sidedef && seg->linedef && seg->linedef->validcount != ::validcount)
			{
				// light is in front of the seg
				if ((pos.Y - seg->v1->fY()) * (seg->v2->fX() - seg->v1->fX()) + (seg->v1->fX() - pos.X) * (seg->v2->fY() - seg->v1->fY()) <= 0)
				{
					seg->linedef->validcount = validcount;
					touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides);
				}
			}
			if (seg->linedef)
			{
				FLinePortal *port = seg->linedef->getPortal();
				if (port && port->mType == PORTT_LINKED)
				{
					line_t *other = port->mDestination;
					if (other->validcount != ::validcount)
					{
						subsector_t *othersub = R_PointInSubsector(other->v1->fPos() + other->Delta() / 2);
						if (othersub->validcount != ::validcount) CollectWithinRadius(PosRelative(other), othersub, radius);
					}
				}
			}

			seg_t *partner = seg->PartnerSeg;
			if (partner)
			{
				subsector_t *sub = partner->Subsector;
				if (sub != NULL && sub->validcount != ::validcount)
				{
					CollectWithinRadius(pos, sub, radius);
				}
			}
		}
	}
	sector_t *sec = subSec->sector;
	if (!sec->PortalBlocksSight(sector_t::ceiling))
	{
		line_t *other = subSec->firstline->linedef;
		if (sec->GetPortalPlaneZ(sector_t::ceiling) < Z() + radius)
		{
			DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::ceiling);
			subsector_t *othersub = R_PointInSubsector(refpos);
			if (othersub->validcount != ::validcount) CollectWithinRadius(PosRelative(othersub->sector), othersub, radius);
		}
	}
	if (!sec->PortalBlocksSight(sector_t::floor))
	{
		line_t *other = subSec->firstline->linedef;
		if (sec->GetPortalPlaneZ(sector_t::floor) > Z() - radius)
		{
			DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::floor);
			subsector_t *othersub = R_PointInSubsector(refpos);
			if (othersub->validcount != ::validcount) CollectWithinRadius(PosRelative(othersub->sector), othersub, radius);
		}
	}
}