Exemple #1
0
aabb2 cast_aabb(game* g, aabb2 self, vec2 delta, int* clipped) {
	aabb2 bounds(expand_toward(self, delta));

	int x0 = fast_floor(bounds.min.x);
	int y0 = fast_floor(bounds.min.y);
	int x1 = fast_floor(bounds.max.x);
	int y1 = fast_floor(bounds.max.y);

	vec2 clipped_delta = delta;

	for(int x = x0; x <= x1; x++) {
		for(int y = y0; y <= y1; y++) {
			if (g->get_tile(x, y) != TT_EMPTY) {
				clipped_delta.x = clip_x(aabb2(vec2((float)x, (float)y), vec2((float)(x + 1), (float)(y + 1))), self, clipped_delta.x);
			}
		}
	}

	self.min.x += clipped_delta.x;
	self.max.x += clipped_delta.x;

	for(int x = x0; x <= x1; x++) {
		for(int y = y0; y <= y1; y++) {
			if (g->get_tile(x, y) != TT_EMPTY) {
				clipped_delta.y = clip_y(aabb2(vec2((float)x, (float)y), vec2((float)(x + 1), (float)(y + 1))), self, clipped_delta.y);
			}
		}
	}

	self.min.y += clipped_delta.y;
	self.max.y += clipped_delta.y;

	if (clipped) {
		*clipped = 0;
		if (delta.x != clipped_delta.x) *clipped |= (delta.x > 0.0f) ? CLIPPED_XP : CLIPPED_XN;
		if (delta.y != clipped_delta.y) *clipped |= (delta.y > 0.0f) ? CLIPPED_YP : CLIPPED_YN;
	}

	return self;
}
bool clip_cg_line
(
    sk_cg_geometry *source,
    int x_min,
    int y_min,
    int x_max,
    int y_max
)
{
    if (!source)
    {
        return false;
    }

    UINT_8 code_a = cohen_code_cg_point(&source->geometry.line.a,
                                        x_min,
                                        y_min,
                                        x_max,
                                        y_max);
    UINT_8 code_b = cohen_code_cg_point(&source->geometry.line.b,
                                        x_min,
                                        y_min,
                                        x_max,
                                        y_max);

    if (code_a & code_b)
    {
        // If line segments are completely outside the window,
        //     c_0 & c_1 != 0
        return false;
    }

    UINT_8 code = code_a ^ code_b;
    UINT_64 x_c = 0;
    UINT_64 y_c = 0;
    while (code)
    {
        if (code & 0x1)
        {
            clip_x(&source->geometry.line.a,
                    &source->geometry.line.b,
                    code_a & 0x1 ? &source->geometry.line.a
                                 : &source->geometry.line.b,
                    x_min);
        }
        else if (code & 0x2)
        {
            clip_x(&source->geometry.line.a,
                    &source->geometry.line.b,
                    code_a & 0x2 ? &source->geometry.line.a
                                 : &source->geometry.line.b,
                    x_max);
        }
        else if (code & 0x4)
        {
            clip_y(&source->geometry.line.a,
                    &source->geometry.line.b,
                    code_a & 0x4 ? &source->geometry.line.a
                                 : &source->geometry.line.b,
                    y_min);
        }
        else if (code & 0x8)
        {
            clip_y(&source->geometry.line.a,
                    &source->geometry.line.b,
                    code_a & 0x8 ? &source->geometry.line.a
                                 : &source->geometry.line.b,
                    y_max);
        }

        code_a = cohen_code_cg_point(&source->geometry.line.a, x_min, y_min, x_max, y_max);
        code_b = cohen_code_cg_point(&source->geometry.line.b, x_min, y_min, x_max, y_max);
        code = code_a ^ code_b;
        continue;
    }

    return !(code_a & code_b);
}