示例#1
0
bool PolyCull::IsSegmentCulled(angle_t startAngle, angle_t endAngle) const
{
	if (startAngle > endAngle)
	{
		return IsSegmentCulled(startAngle, ANGLE_MAX) && IsSegmentCulled(0, endAngle);
	}

	for (const auto &segment : SolidSegments)
	{
		if (startAngle >= segment.Start && endAngle <= segment.End)
			return true;
		else if (endAngle < segment.Start)
			return false;
	}
	return false;
}
示例#2
0
bool PolyCull::CheckBBox(float *bspcoord)
{
	// Occlusion test using solid segments:
	static const uint8_t checkcoord[12][4] =
	{
		{ 3,0,2,1 },
		{ 3,0,2,0 },
		{ 3,1,2,0 },
		{ 0 },
		{ 2,0,2,1 },
		{ 0,0,0,0 },
		{ 3,1,3,0 },
		{ 0 },
		{ 2,0,3,1 },
		{ 2,1,3,1 },
		{ 2,1,3,0 }
	};

	// Find the corners of the box that define the edges from current viewpoint.
	const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
	int boxpos = (viewpoint.Pos.X <= bspcoord[BOXLEFT] ? 0 : viewpoint.Pos.X < bspcoord[BOXRIGHT] ? 1 : 2) +
		(viewpoint.Pos.Y >= bspcoord[BOXTOP] ? 0 : viewpoint.Pos.Y > bspcoord[BOXBOTTOM] ? 4 : 8);

	if (boxpos == 5) return true;

	const uint8_t *check = checkcoord[boxpos];
	angle_t angle1 = PointToPseudoAngle(bspcoord[check[0]], bspcoord[check[1]]);
	angle_t angle2 = PointToPseudoAngle(bspcoord[check[2]], bspcoord[check[3]]);

	return !IsSegmentCulled(angle2, angle1);
}
bool PolyCull::CheckBBox(float *bspcoord)
{
    // Start using a quick frustum AABB test:

    AxisAlignedBoundingBox aabb(Vec3f(bspcoord[BOXLEFT], bspcoord[BOXBOTTOM], (float)ViewPos.Z - 1000.0f), Vec3f(bspcoord[BOXRIGHT], bspcoord[BOXTOP], (float)ViewPos.Z + 1000.0f));
    auto result = IntersectionTest::frustum_aabb(frustumPlanes, aabb);
    if (result == IntersectionTest::outside)
        return false;

    // Occlusion test using solid segments:

    static const int lines[4][4] =
    {
        { BOXLEFT,  BOXBOTTOM, BOXRIGHT, BOXBOTTOM },
        { BOXRIGHT, BOXBOTTOM, BOXRIGHT, BOXTOP    },
        { BOXRIGHT, BOXTOP,    BOXLEFT,  BOXTOP    },
        { BOXLEFT,  BOXTOP,    BOXLEFT,  BOXBOTTOM }
    };

    bool foundline = false;
    int minsx1, maxsx2;
    for (int i = 0; i < 4; i++)
    {
        int j = i < 3 ? i + 1 : 0;
        float x1 = bspcoord[lines[i][0]];
        float y1 = bspcoord[lines[i][1]];
        float x2 = bspcoord[lines[i][2]];
        float y2 = bspcoord[lines[i][3]];
        int sx1, sx2;
        if (GetSegmentRangeForLine(x1, y1, x2, y2, sx1, sx2))
        {
            if (foundline)
            {
                minsx1 = MIN(minsx1, sx1);
                maxsx2 = MAX(maxsx2, sx2);
            }
            else
            {
                minsx1 = sx1;
                maxsx2 = sx2;
                foundline = true;
            }
        }
    }
    if (!foundline)
        return false;

    return !IsSegmentCulled(minsx1, maxsx2);
}
示例#4
0
bool PolyCull::GetAnglesForLine(double x1, double y1, double x2, double y2, angle_t &angle1, angle_t &angle2) const
{
	angle2 = PointToPseudoAngle(x1, y1);
	angle1 = PointToPseudoAngle(x2, y2);
	return !IsSegmentCulled(angle1, angle2);
}