Ejemplo n.º 1
0
void ADynamicLight::LinkLight()
{
	// mark the old light nodes
	FLightNode * node;
	
	node = touching_sides;
	while (node)
    {
		node->lightsource = NULL;
		node = node->nextTarget;
    }
	node = touching_subsectors;
	while (node)
    {
		node->lightsource = NULL;
		node = node->nextTarget;
    }

	if (radius>0)
	{
		// passing in radius*radius allows us to do a distance check without any calls to sqrtf
		::validcount++;
		subsector_t * subSec = R_PointInSubsector(x, y);
		if (subSec)
		{
			float fradius = FIXED2FLOAT(radius);
			CollectWithinRadius(subSec, fradius*fradius);
		}
	}
		
	// Now delete any nodes that won't be used. These are the ones where
	// m_thing is still NULL.
	
	node = touching_sides;
	while (node)
	{
		if (node->lightsource == NULL)
		{
			node = DeleteLightNode(node);
		}
		else
			node = node->nextTarget;
	}

	node = touching_subsectors;
	while (node)
	{
		if (node->lightsource == NULL)
		{
			node = DeleteLightNode(node);
		}
		else
			node = node->nextTarget;
	}
}
Ejemplo n.º 2
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.º 3
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);
		}
	}
}