Add a blend pattern that maps to two individual patterns
This commit is contained in:
parent
d5ba13b2fe
commit
0ee822046b
@ -12,20 +12,24 @@
|
||||
|
||||
CEXCEPTION_T global_exception;
|
||||
void build_world(WORLD_World* world) {
|
||||
TUPLES_Color red, green, blue;
|
||||
TUPLES_Color red, green, blue, black, gray, white;
|
||||
TUPLES_init_color(&red, 1, 0, 0);
|
||||
TUPLES_init_color(&green, 0, 1, 0);
|
||||
TUPLES_init_color(&blue, 0, 0, 1);
|
||||
PLANE_Plane* floor = PLANE_new();
|
||||
TUPLES_init_color(&black, 0, 0, 0);
|
||||
TUPLES_init_color(&gray, .25, .25, .25);
|
||||
TUPLES_init_color(&white, 1, 1, 1);
|
||||
PLANE_Plane* floor = PLANE_new();
|
||||
WORLD_add_object(world, floor);
|
||||
MATERIAL_Material* material = MATERIAL_new();
|
||||
material->specular = 0;
|
||||
PATTERN_Pattern* floor_pattern = PATTERN_new_stripe(&red, &green);
|
||||
MATRIX_Matrix* pattern_transform = MATRIX_new_rotation_y(-M_PI / 5);
|
||||
PATTERN_set_transform(floor_pattern, pattern_transform);
|
||||
MATRIX_delete(pattern_transform);
|
||||
PATTERN_Pattern* floor_pattern_a = PATTERN_new_stripe(&white, &gray);
|
||||
PATTERN_Pattern* floor_pattern_b = PATTERN_new_stripe(&white, &gray);
|
||||
MATRIX_Matrix *rot_y = MATRIX_new_rotation_y(M_PI_4);
|
||||
PATTERN_set_transform(floor_pattern_b, rot_y);
|
||||
MATRIX_delete(rot_y);
|
||||
PATTERN_Pattern *floor_pattern = PATTERN_new_blended(floor_pattern_a, floor_pattern_b);
|
||||
MATERIAL_set_pattern(material, floor_pattern);
|
||||
PATTERN_delete(floor_pattern);
|
||||
PLANE_set_material(floor, material);
|
||||
MATERIAL_delete(material);
|
||||
|
||||
|
@ -66,6 +66,7 @@ static void copy_base_pattern_in_place(PATTERN_Pattern *dest, const PATTERN_Patt
|
||||
MATRIX_copy(dest->inverse_transform, src->inverse_transform);
|
||||
dest->at = src->at;
|
||||
dest->copy = src->copy;
|
||||
dest->delete = src->delete;
|
||||
}
|
||||
|
||||
const TUPLES_Color *PATTERN_get_color_a(const PATTERN_Pattern *pattern) {
|
||||
@ -311,6 +312,7 @@ void cube_map_at(TUPLES_Color *dest, const PATTERN_Pattern *pattern, const TUPLE
|
||||
static PATTERN_Pattern *copy_cube_map(const PATTERN_Pattern *pattern) {
|
||||
assert(pattern);
|
||||
PATTERN_Pattern_Cube_Map *cube_map = (PATTERN_Pattern_Cube_Map*)pattern;
|
||||
copy_base_pattern_in_place(&cube_map->pattern, pattern);
|
||||
return PATTERN_new_cube_map(cube_map->uv_pattern[UV_PATTERN_LEFT],
|
||||
cube_map->uv_pattern[UV_PATTERN_FRONT],
|
||||
cube_map->uv_pattern[UV_PATTERN_RIGHT],
|
||||
@ -355,3 +357,62 @@ PATTERN_Pattern *PATTERN_new_cube_map(const UV_Pattern *left, const UV_Pattern *
|
||||
return (PATTERN_Pattern*)map;
|
||||
}
|
||||
|
||||
//---- blended patterns
|
||||
typedef struct {
|
||||
PATTERN_Pattern pattern;
|
||||
PATTERN_Pattern *a;
|
||||
PATTERN_Pattern *b;
|
||||
} PATTERN_Pattern_Blended;
|
||||
|
||||
void blended_map_at(TUPLES_Color *dest, const PATTERN_Pattern *pattern, const TUPLES_Point *point) {
|
||||
assert(dest);
|
||||
assert(pattern);
|
||||
assert(point);
|
||||
PATTERN_Pattern_Blended *bpat = (PATTERN_Pattern_Blended*)pattern;
|
||||
|
||||
TUPLES_Point pattern_a_point, pattern_b_point;
|
||||
MATRIX_multiply_tuple(&pattern_a_point, bpat->a->inverse_transform, point);
|
||||
MATRIX_multiply_tuple(&pattern_b_point, bpat->b->inverse_transform, point);
|
||||
|
||||
TUPLES_Color a_color, b_color;
|
||||
PATTERN_color_at(&a_color, bpat->a, &pattern_a_point);
|
||||
PATTERN_color_at(&b_color, bpat->b, &pattern_b_point);
|
||||
TUPLES_add(dest, &a_color, &b_color);
|
||||
TUPLES_divide(dest, dest, 2);
|
||||
}
|
||||
|
||||
static PATTERN_Pattern *copy_blended_map(const PATTERN_Pattern *pattern) {
|
||||
assert(pattern);
|
||||
PATTERN_Pattern_Blended *bpat = (PATTERN_Pattern_Blended*)pattern;
|
||||
PATTERN_Pattern *a = PATTERN_new_copy(bpat->a);
|
||||
PATTERN_Pattern *b = PATTERN_new_copy(bpat->b);
|
||||
PATTERN_Pattern *copy = PATTERN_new_blended(a, b);
|
||||
copy_base_pattern_in_place(copy, pattern);
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void delete_blended_map(PATTERN_Pattern *pattern) {
|
||||
assert(pattern);
|
||||
PATTERN_Pattern_Blended *bpat = (PATTERN_Pattern_Blended*)pattern;
|
||||
PATTERN_delete(bpat->a);
|
||||
PATTERN_delete(bpat->b);
|
||||
delete_base_pattern(&bpat->pattern);
|
||||
}
|
||||
|
||||
PATTERN_Pattern *PATTERN_new_blended(PATTERN_Pattern *a, PATTERN_Pattern *b) {
|
||||
assert(a);
|
||||
assert(b);
|
||||
PATTERN_Pattern_Blended *pattern = malloc(sizeof(PATTERN_Pattern_Blended));
|
||||
if (!pattern) {
|
||||
Throw(E_MALLOC_FAILED);
|
||||
}
|
||||
TUPLES_Color dummy_color;
|
||||
TUPLES_init_color(&dummy_color, 0, 0, 0);
|
||||
PATTERN_init(&pattern->pattern, &dummy_color, &dummy_color);
|
||||
pattern->pattern.at = &blended_map_at;
|
||||
pattern->pattern.copy = ©_blended_map;
|
||||
pattern->pattern.delete = &delete_blended_map;
|
||||
pattern->a = a;
|
||||
pattern->b = b;
|
||||
return (PATTERN_Pattern*)pattern;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ PATTERN_Pattern *PATTERN_new_checkers(const TUPLES_Color *a, const TUPLES_Color
|
||||
PATTERN_Pattern *PATTERN_new_solid(const TUPLES_Color *a);
|
||||
PATTERN_Pattern *PATTERN_new_map(const UV_Pattern* uv_pattern, void (*map)(double* u, double* v, const TUPLES_Point* point));
|
||||
PATTERN_Pattern *PATTERN_new_cube_map(const UV_Pattern *left, const UV_Pattern *front, const UV_Pattern *right, const UV_Pattern *back, const UV_Pattern *up, const UV_Pattern *down);
|
||||
PATTERN_Pattern *PATTERN_new_blended(PATTERN_Pattern *a, PATTERN_Pattern *b);
|
||||
|
||||
const TUPLES_Color *PATTERN_get_color_a(const PATTERN_Pattern *pattern);
|
||||
const TUPLES_Color *PATTERN_get_color_b(const PATTERN_Pattern *pattern);
|
||||
|
@ -260,6 +260,20 @@ void test_solid_pattern_is_always_same() {
|
||||
PATTERN_delete(pattern);
|
||||
}
|
||||
|
||||
void test_blended_pattern_takes_ownership_of_sub_patterns() {
|
||||
TUPLES_Color *gray = TUPLES_new_color(.5, .5, .5);
|
||||
PATTERN_Pattern *a = PATTERN_new_stripe(white, gray);
|
||||
MATRIX_Matrix *rot_y = MATRIX_new_rotation_y(M_PI_2);
|
||||
PATTERN_set_transform(a, rot_y);
|
||||
MATRIX_delete(rot_y);
|
||||
PATTERN_Pattern *b = PATTERN_new_stripe(white, gray);
|
||||
TUPLES_delete(gray);
|
||||
|
||||
PATTERN_Pattern *blend = PATTERN_new_blended(a, b);
|
||||
|
||||
PATTERN_delete(blend);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_create_pattern);
|
||||
@ -278,5 +292,6 @@ int main(void) {
|
||||
RUN_TEST(test_checkers_repeat_in_y);
|
||||
RUN_TEST(test_checkers_repeat_in_z);
|
||||
RUN_TEST(test_solid_pattern_is_always_same);
|
||||
RUN_TEST(test_blended_pattern_takes_ownership_of_sub_patterns);
|
||||
return UNITY_END();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user