Exemplo n.º 1
0
void PolyCull::CullScene(const TriMatrix &worldToClip, const PolyClipPlane &portalClipPlane)
{
	PvsSectors.clear();
	PortalClipPlane = portalClipPlane;

	// Cull front to back
	FirstSkyHeight = true;
	MaxCeilingHeight = 0.0;
	MinFloorHeight = 0.0;
	if (level.nodes.Size() == 0)
		CullSubsector(&level.subsectors[0]);
	else
		CullNode(level.HeadNode());
}
Exemplo n.º 2
0
void PolyCull::CullScene(const PolyClipPlane &portalClipPlane)
{
	ClearSolidSegments();
	MarkViewFrustum();

	if (level.LevelName != lastLevelName) // Is this the best way to detect a level change?
	{
		lastLevelName = level.LevelName;
		SubsectorDepths.clear();
		SubsectorDepths.resize(level.subsectors.Size(), 0xffffffff);
		SectorSeen.clear();
		SectorSeen.resize(level.sectors.Size());
	}
	else
	{
		for (const auto &sub : PvsSectors)
			SubsectorDepths[sub->Index()] = 0xffffffff;
		SubsectorDepths.resize(level.subsectors.Size(), 0xffffffff);

		for (const auto &sector : SeenSectors)
			SectorSeen[sector->Index()] = false;
		SectorSeen.resize(level.sectors.Size());
	}

	PvsSectors.clear();
	SeenSectors.clear();

	NextPvsLineStart = 0;
	PvsLineStart.clear();
	PvsLineVisible.resize(level.segs.Size());

	PortalClipPlane = portalClipPlane;

	// Cull front to back
	FirstSkyHeight = true;
	MaxCeilingHeight = 0.0;
	MinFloorHeight = 0.0;
	if (level.nodes.Size() == 0)
		CullSubsector(&level.subsectors[0]);
	else
		CullNode(level.HeadNode());
}
Exemplo n.º 3
0
void PolyCull::CullNode(void *node)
{
    while (!((size_t)node & 1))  // Keep going until found a subsector
    {
        node_t *bsp = (node_t *)node;

        // Decide which side the view point is on.
        int side = PointOnSide(ViewPos, bsp);

        // Recursively divide front space (toward the viewer).
        CullNode(bsp->children[side]);

        // Possibly divide back space (away from the viewer).
        side ^= 1;
        if (!CheckBBox(bsp->bbox[side]))
            return;

        node = bsp->children[side];
    }

    // Mark that we need to render this
    subsector_t *sub = (subsector_t *)((BYTE *)node - 1);
    MaxCeilingHeight = MAX(MaxCeilingHeight, sub->sector->ceilingplane.Zat0());
    MinFloorHeight = MIN(MinFloorHeight, sub->sector->floorplane.Zat0());
    PvsSectors.push_back(sub);

    // Update culling info for further bsp clipping
    for (uint32_t i = 0; i < sub->numlines; i++)
    {
        seg_t *line = &sub->firstline[i];
        if ((line->sidedef == nullptr || !(line->sidedef->Flags & WALLF_POLYOBJ)) && line->backsector == nullptr)
        {
            int sx1, sx2;
            if (GetSegmentRangeForLine(line->v1->fX(), line->v1->fY(), line->v2->fX(), line->v2->fY(), sx1, sx2))
            {
                MarkSegmentCulled(sx1, sx2);
            }
        }
    }
}
Exemplo n.º 4
0
void PolyCull::CullScene(const TriMatrix &worldToClip)
{
    ClearSolidSegments();
    PvsSectors.clear();
    frustumPlanes = FrustumPlanes(worldToClip);

    // Cull front to back
    if (numnodes == 0)
    {
        PvsSectors.push_back(subsectors);
        MaxCeilingHeight = subsectors->sector->ceilingplane.Zat0();
        MinFloorHeight = subsectors->sector->floorplane.Zat0();
    }
    else
    {
        MaxCeilingHeight = 0.0;
        MinFloorHeight = 0.0;
        CullNode(nodes + numnodes - 1);	// The head node is the last node output.
    }

    ClearSolidSegments();
}
Exemplo n.º 5
0
void PolyCull::CullNode(void *node)
{
	while (!((size_t)node & 1))  // Keep going until found a subsector
	{
		node_t *bsp = (node_t *)node;

		// Decide which side the view point is on.
		int side = PointOnSide(PolyRenderer::Instance()->Viewpoint.Pos, bsp);

		// Recursively divide front space (toward the viewer).
		CullNode(bsp->children[side]);

		// Possibly divide back space (away from the viewer).
		side ^= 1;

		if (!CheckBBox(bsp->bbox[side]))
			return;

		node = bsp->children[side];
	}

	subsector_t *sub = (subsector_t *)((uint8_t *)node - 1);
	CullSubsector(sub);
}