Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
| Context not available. | |||||
| /* See if there is any already allocated memory we can reuse. */ | /* See if there is any already allocated memory we can reuse. */ | ||||
| if (rb->wasted_cuts.first) { | if (rb->wasted_cuts.first) { | ||||
| LineartLineSegment *rls = (LineartLineSegment *)BLI_pophead(&rb->wasted_cuts); | LineartLineSegment *rls = (LineartLineSegment *)BLI_pophead(&rb->wasted_cuts); | ||||
| BLI_spin_unlock(&rb->lock_cuts); | BLI_spin_unlock(&rb->lock_cuts); | ||||
| memset(rls, 0, sizeof(LineartLineSegment)); | memset(rls, 0, sizeof(LineartLineSegment)); | ||||
| return rls; | return rls; | ||||
| } | } | ||||
| BLI_spin_unlock(&rb->lock_cuts); | BLI_spin_unlock(&rb->lock_cuts); | ||||
| /* Otherwise allocate some new memory. */ | /* Otherwise allocate some new memory. */ | ||||
| return (LineartLineSegment *)lineart_mem_aquire_thread(&rb->render_data_pool, | return (LineartLineSegment *)lineart_mem_acquire_thread(&rb->render_data_pool, | ||||
| sizeof(LineartLineSegment)); | sizeof(LineartLineSegment)); | ||||
| } | } | ||||
| /** | /** | ||||
| * Cuts the edge in image space and mark occlusion level for each segment. | * Cuts the edge in image space and mark occlusion level for each segment. | ||||
| */ | */ | ||||
| static void lineart_edge_cut( | static void lineart_edge_cut( | ||||
| LineartRenderBuffer *rb, LineartEdge *e, double start, double end, uchar transparency_mask) | LineartRenderBuffer *rb, LineartEdge *e, double start, double end, uchar transparency_mask) | ||||
| { | { | ||||
| LineartLineSegment *rls, *irls, *next_rls, *prev_rls; | LineartLineSegment *rls, *irls, *next_rls, *prev_rls; | ||||
| Context not available. | |||||
| /** | /** | ||||
| * The following `lineart_memory_get_XXX_space` functions are for allocating new memory for some | * The following `lineart_memory_get_XXX_space` functions are for allocating new memory for some | ||||
| * modified geometries in the culling stage. | * modified geometries in the culling stage. | ||||
| */ | */ | ||||
| static LineartElementLinkNode *lineart_memory_get_triangle_space(LineartRenderBuffer *rb) | static LineartElementLinkNode *lineart_memory_get_triangle_space(LineartRenderBuffer *rb) | ||||
| { | { | ||||
| LineartElementLinkNode *reln; | LineartElementLinkNode *reln; | ||||
| /* We don't need to allocate a whole bunch of triangles because the amount of clipped triangles | /* We don't need to allocate a whole bunch of triangles because the amount of clipped triangles | ||||
| * are relatively small. */ | * are relatively small. */ | ||||
| LineartTriangle *render_triangles = lineart_mem_aquire(&rb->render_data_pool, | LineartTriangle *render_triangles = lineart_mem_acquire(&rb->render_data_pool, | ||||
| 64 * rb->triangle_size); | 64 * rb->triangle_size); | ||||
| reln = lineart_list_append_pointer_pool_sized(&rb->triangle_buffer_pointers, | reln = lineart_list_append_pointer_pool_sized(&rb->triangle_buffer_pointers, | ||||
| &rb->render_data_pool, | &rb->render_data_pool, | ||||
| render_triangles, | render_triangles, | ||||
| sizeof(LineartElementLinkNode)); | sizeof(LineartElementLinkNode)); | ||||
| reln->element_count = 64; | reln->element_count = 64; | ||||
| reln->flags |= LRT_ELEMENT_IS_ADDITIONAL; | reln->flags |= LRT_ELEMENT_IS_ADDITIONAL; | ||||
| return reln; | return reln; | ||||
| } | } | ||||
| static LineartElementLinkNode *lineart_memory_get_vert_space(LineartRenderBuffer *rb) | static LineartElementLinkNode *lineart_memory_get_vert_space(LineartRenderBuffer *rb) | ||||
| { | { | ||||
| LineartElementLinkNode *reln; | LineartElementLinkNode *reln; | ||||
| LineartVert *render_vertices = lineart_mem_aquire(&rb->render_data_pool, | LineartVert *render_vertices = lineart_mem_acquire(&rb->render_data_pool, | ||||
| sizeof(LineartVert) * 64); | sizeof(LineartVert) * 64); | ||||
| reln = lineart_list_append_pointer_pool_sized(&rb->vertex_buffer_pointers, | reln = lineart_list_append_pointer_pool_sized(&rb->vertex_buffer_pointers, | ||||
| &rb->render_data_pool, | &rb->render_data_pool, | ||||
| render_vertices, | render_vertices, | ||||
| sizeof(LineartElementLinkNode)); | sizeof(LineartElementLinkNode)); | ||||
| reln->element_count = 64; | reln->element_count = 64; | ||||
| reln->flags |= LRT_ELEMENT_IS_ADDITIONAL; | reln->flags |= LRT_ELEMENT_IS_ADDITIONAL; | ||||
| return reln; | return reln; | ||||
| } | } | ||||
| static LineartElementLinkNode *lineart_memory_get_edge_space(LineartRenderBuffer *rb) | static LineartElementLinkNode *lineart_memory_get_edge_space(LineartRenderBuffer *rb) | ||||
| { | { | ||||
| LineartElementLinkNode *reln; | LineartElementLinkNode *reln; | ||||
| LineartEdge *render_edges = lineart_mem_aquire(&rb->render_data_pool, sizeof(LineartEdge) * 64); | LineartEdge *render_edges = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdge) * 64); | ||||
| reln = lineart_list_append_pointer_pool_sized(&rb->line_buffer_pointers, | reln = lineart_list_append_pointer_pool_sized(&rb->line_buffer_pointers, | ||||
| &rb->render_data_pool, | &rb->render_data_pool, | ||||
| render_edges, | render_edges, | ||||
| sizeof(LineartElementLinkNode)); | sizeof(LineartElementLinkNode)); | ||||
| reln->element_count = 64; | reln->element_count = 64; | ||||
| reln->crease_threshold = rb->crease_threshold; | reln->crease_threshold = rb->crease_threshold; | ||||
| reln->flags |= LRT_ELEMENT_IS_ADDITIONAL; | reln->flags |= LRT_ELEMENT_IS_ADDITIONAL; | ||||
| return reln; | return reln; | ||||
| Context not available. | |||||
| e = new_e; | e = new_e; | ||||
| #define INCREASE_RL \ | #define INCREASE_RL \ | ||||
| e_count++; \ | e_count++; \ | ||||
| v1_obi = e->v1_obindex; \ | v1_obi = e->v1_obindex; \ | ||||
| v2_obi = e->v2_obindex; \ | v2_obi = e->v2_obindex; \ | ||||
| new_e = &((LineartEdge *)e_eln->pointer)[e_count]; \ | new_e = &((LineartEdge *)e_eln->pointer)[e_count]; \ | ||||
| e = new_e; \ | e = new_e; \ | ||||
| e->v1_obindex = v1_obi; \ | e->v1_obindex = v1_obi; \ | ||||
| e->v2_obindex = v2_obi; \ | e->v2_obindex = v2_obi; \ | ||||
| rls = lineart_mem_aquire(&rb->render_data_pool, sizeof(LineartLineSegment)); \ | rls = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartLineSegment)); \ | ||||
| BLI_addtail(&e->segments, rls); | BLI_addtail(&e->segments, rls); | ||||
| #define SELECT_RL(e_num, v1_link, v2_link, newrt) \ | #define SELECT_RL(e_num, v1_link, v2_link, newrt) \ | ||||
| if (rta->e[e_num]) { \ | if (rta->e[e_num]) { \ | ||||
| old_e = rta->e[e_num]; \ | old_e = rta->e[e_num]; \ | ||||
| new_flag = old_e->flags; \ | new_flag = old_e->flags; \ | ||||
| old_e->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \ | old_e->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \ | ||||
| INCREASE_RL \ | INCREASE_RL \ | ||||
| e->v1 = (v1_link); \ | e->v1 = (v1_link); \ | ||||
| e->v2 = (v2_link); \ | e->v2 = (v2_link); \ | ||||
| Context not available. | |||||
| BM_mesh_normals_update(bm); | BM_mesh_normals_update(bm); | ||||
| BM_mesh_elem_table_ensure(bm, BM_VERT | BM_EDGE | BM_FACE); | BM_mesh_elem_table_ensure(bm, BM_VERT | BM_EDGE | BM_FACE); | ||||
| BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE | BM_FACE); | BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE | BM_FACE); | ||||
| if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) { | if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) { | ||||
| CanFindFreestyle = 1; | CanFindFreestyle = 1; | ||||
| } | } | ||||
| /* Only allocate memory for verts and tris as we don't know how many lines we will generate | /* Only allocate memory for verts and tris as we don't know how many lines we will generate | ||||
| * yet. */ | * yet. */ | ||||
| orv = lineart_mem_aquire(&rb->render_data_pool, sizeof(LineartVert) * bm->totvert); | orv = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartVert) * bm->totvert); | ||||
| ort = lineart_mem_aquire(&rb->render_data_pool, bm->totface * rb->triangle_size); | ort = lineart_mem_acquire(&rb->render_data_pool, bm->totface * rb->triangle_size); | ||||
| orig_ob = ob->id.orig_id ? (Object *)ob->id.orig_id : ob; | orig_ob = ob->id.orig_id ? (Object *)ob->id.orig_id : ob; | ||||
| reln = lineart_list_append_pointer_pool_sized( | reln = lineart_list_append_pointer_pool_sized( | ||||
| &rb->vertex_buffer_pointers, &rb->render_data_pool, orv, sizeof(LineartElementLinkNode)); | &rb->vertex_buffer_pointers, &rb->render_data_pool, orv, sizeof(LineartElementLinkNode)); | ||||
| reln->element_count = bm->totvert; | reln->element_count = bm->totvert; | ||||
| reln->object_ref = orig_ob; | reln->object_ref = orig_ob; | ||||
| if (ob->lineart.flags & OBJECT_LRT_OWN_CREASE) { | if (ob->lineart.flags & OBJECT_LRT_OWN_CREASE) { | ||||
| use_crease = cosf(M_PI - ob->lineart.crease_threshold); | use_crease = cosf(M_PI - ob->lineart.crease_threshold); | ||||
| Context not available. | |||||
| if (eflag) { | if (eflag) { | ||||
| /* Only allocate for feature lines (instead of all lines) to save memory. */ | /* Only allocate for feature lines (instead of all lines) to save memory. */ | ||||
| allocate_la_e++; | allocate_la_e++; | ||||
| } | } | ||||
| /* Here we just use bm's flag for when loading actual lines, then we don't need to call | /* Here we just use bm's flag for when loading actual lines, then we don't need to call | ||||
| * lineart_identify_feature_line() again, e->head.hflag deleted after loading anyway. Always | * lineart_identify_feature_line() again, e->head.hflag deleted after loading anyway. Always | ||||
| * set the flag, so hflag stays 0 for lines that are not feature lines. */ | * set the flag, so hflag stays 0 for lines that are not feature lines. */ | ||||
| e->head.hflag = eflag; | e->head.hflag = eflag; | ||||
| } | } | ||||
| o_la_e = lineart_mem_aquire(&rb->render_data_pool, sizeof(LineartEdge) * allocate_la_e); | o_la_e = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdge) * allocate_la_e); | ||||
| reln = lineart_list_append_pointer_pool_sized( | reln = lineart_list_append_pointer_pool_sized( | ||||
| &rb->line_buffer_pointers, &rb->render_data_pool, o_la_e, sizeof(LineartElementLinkNode)); | &rb->line_buffer_pointers, &rb->render_data_pool, o_la_e, sizeof(LineartElementLinkNode)); | ||||
| reln->element_count = allocate_la_e; | reln->element_count = allocate_la_e; | ||||
| reln->object_ref = orig_ob; | reln->object_ref = orig_ob; | ||||
| la_e = o_la_e; | la_e = o_la_e; | ||||
| for (i = 0; i < bm->totedge; i++) { | for (i = 0; i < bm->totedge; i++) { | ||||
| e = BM_edge_at_index(bm, i); | e = BM_edge_at_index(bm, i); | ||||
| /* Not a feature line, so we skip. */ | /* Not a feature line, so we skip. */ | ||||
| Context not available. | |||||
| lineart_triangle_adjacent_assign(la_e->t1, &orta[findex], la_e); | lineart_triangle_adjacent_assign(la_e->t1, &orta[findex], la_e); | ||||
| if (e->l->radial_next && e->l->radial_next != e->l) { | if (e->l->radial_next && e->l->radial_next != e->l) { | ||||
| findex = BM_elem_index_get(e->l->radial_next->f); | findex = BM_elem_index_get(e->l->radial_next->f); | ||||
| la_e->t2 = lineart_triangle_from_index(rb, ort, findex); | la_e->t2 = lineart_triangle_from_index(rb, ort, findex); | ||||
| lineart_triangle_adjacent_assign(la_e->t2, &orta[findex], la_e); | lineart_triangle_adjacent_assign(la_e->t2, &orta[findex], la_e); | ||||
| } | } | ||||
| } | } | ||||
| la_e->flags = e->head.hflag; | la_e->flags = e->head.hflag; | ||||
| la_e->object_ref = orig_ob; | la_e->object_ref = orig_ob; | ||||
| LineartLineSegment *rls = lineart_mem_aquire(&rb->render_data_pool, | LineartLineSegment *rls = lineart_mem_acquire(&rb->render_data_pool, | ||||
| sizeof(LineartLineSegment)); | sizeof(LineartLineSegment)); | ||||
| BLI_addtail(&la_e->segments, rls); | BLI_addtail(&la_e->segments, rls); | ||||
| if (ELEM(usage, OBJECT_LRT_INHERIT, OBJECT_LRT_INCLUDE, OBJECT_LRT_NO_INTERSECTION)) { | if (ELEM(usage, OBJECT_LRT_INHERIT, OBJECT_LRT_INCLUDE, OBJECT_LRT_NO_INTERSECTION)) { | ||||
| lineart_add_edge_to_list(rb, la_e); | lineart_add_edge_to_list(rb, la_e); | ||||
| } | } | ||||
| la_e++; | la_e++; | ||||
| } | } | ||||
| LRT_MESH_FINISH | LRT_MESH_FINISH | ||||
| Context not available. | |||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| if (!(lineart_point_inside_triangle3d( | if (!(lineart_point_inside_triangle3d( | ||||
| gloc, testing->v[0]->gloc, testing->v[1]->gloc, testing->v[2]->gloc))) { | gloc, testing->v[0]->gloc, testing->v[1]->gloc, testing->v[2]->gloc))) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| /* This is an intersection vert, the size is bigger than LineartVert, | /* This is an intersection vert, the size is bigger than LineartVert, | ||||
| * allocated separately. */ | * allocated separately. */ | ||||
| result = lineart_mem_aquire(&rb->render_data_pool, sizeof(LineartVertIntersection)); | result = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartVertIntersection)); | ||||
| /* Indicate the data structure difference. */ | /* Indicate the data structure difference. */ | ||||
| result->flag = LRT_VERT_HAS_INTERSECTION_DATA; | result->flag = LRT_VERT_HAS_INTERSECTION_DATA; | ||||
| copy_v3_v3_db(result->gloc, gloc); | copy_v3_v3_db(result->gloc, gloc); | ||||
| lineart_prepend_pool(&testing->intersecting_verts, &rb->render_data_pool, result); | lineart_prepend_pool(&testing->intersecting_verts, &rb->render_data_pool, result); | ||||
| return result; | return result; | ||||
| } | } | ||||
| Context not available. | |||||
| copy_v3_v3_db(cl, rb->camera_pos); | copy_v3_v3_db(cl, rb->camera_pos); | ||||
| LineartVert *share = lineart_triangle_share_point(testing, rt); | LineartVert *share = lineart_triangle_share_point(testing, rt); | ||||
| if (share) { | if (share) { | ||||
| /* If triangles have sharing points like `abc` and `acd`, then we only need to detect `bc` | /* If triangles have sharing points like `abc` and `acd`, then we only need to detect `bc` | ||||
| * against `acd` or `cd` against `abc`. */ | * against `acd` or `cd` against `abc`. */ | ||||
| LineartVert *new_share; | LineartVert *new_share; | ||||
| lineart_triangle_get_other_verts(rt, share, &sv1, &sv2); | lineart_triangle_get_other_verts(rt, share, &sv1, &sv2); | ||||
| v1 = new_share = lineart_mem_aquire(&rb->render_data_pool, (sizeof(LineartVertIntersection))); | v1 = new_share = lineart_mem_acquire(&rb->render_data_pool, (sizeof(LineartVertIntersection))); | ||||
| new_share->flag = LRT_VERT_HAS_INTERSECTION_DATA; | new_share->flag = LRT_VERT_HAS_INTERSECTION_DATA; | ||||
| copy_v3_v3_db(new_share->gloc, share->gloc); | copy_v3_v3_db(new_share->gloc, share->gloc); | ||||
| v2 = lineart_triangle_2v_intersection_test(rb, sv1, sv2, rt, testing, 0); | v2 = lineart_triangle_2v_intersection_test(rb, sv1, sv2, rt, testing, 0); | ||||
| if (v2 == NULL) { | if (v2 == NULL) { | ||||
| lineart_triangle_get_other_verts(testing, share, &sv1, &sv2); | lineart_triangle_get_other_verts(testing, share, &sv1, &sv2); | ||||
| v2 = lineart_triangle_2v_intersection_test(rb, sv1, sv2, testing, rt, 0); | v2 = lineart_triangle_2v_intersection_test(rb, sv1, sv2, testing, rt, 0); | ||||
| Context not available. | |||||
| /* This z transformation is not the same as the rest of the part, because the data don't go | /* This z transformation is not the same as the rest of the part, because the data don't go | ||||
| * through normal perspective division calls in the pipeline, but this way the 3D result and | * through normal perspective division calls in the pipeline, but this way the 3D result and | ||||
| * occlusion on the generated line is correct, and we don't really use 2D for viewport stroke | * occlusion on the generated line is correct, and we don't really use 2D for viewport stroke | ||||
| * generation anyway. */ | * generation anyway. */ | ||||
| v1->fbcoord[2] = ZMin * ZMax / (ZMax - fabs(v1->fbcoord[2]) * (ZMax - ZMin)); | v1->fbcoord[2] = ZMin * ZMax / (ZMax - fabs(v1->fbcoord[2]) * (ZMax - ZMin)); | ||||
| v2->fbcoord[2] = ZMin * ZMax / (ZMax - fabs(v2->fbcoord[2]) * (ZMax - ZMin)); | v2->fbcoord[2] = ZMin * ZMax / (ZMax - fabs(v2->fbcoord[2]) * (ZMax - ZMin)); | ||||
| ((LineartVertIntersection *)v1)->intersecting_with = rt; | ((LineartVertIntersection *)v1)->intersecting_with = rt; | ||||
| ((LineartVertIntersection *)v2)->intersecting_with = testing; | ((LineartVertIntersection *)v2)->intersecting_with = testing; | ||||
| result = lineart_mem_aquire(&rb->render_data_pool, sizeof(LineartEdge)); | result = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdge)); | ||||
| result->v1 = v1; | result->v1 = v1; | ||||
| result->v2 = v2; | result->v2 = v2; | ||||
| result->t1 = rt; | result->t1 = rt; | ||||
| result->t2 = testing; | result->t2 = testing; | ||||
| LineartLineSegment *rls = lineart_mem_aquire(&rb->render_data_pool, sizeof(LineartLineSegment)); | LineartLineSegment *rls = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartLineSegment)); | ||||
| BLI_addtail(&result->segments, rls); | BLI_addtail(&result->segments, rls); | ||||
| /* Don't need to OR flags right now, just a type mark. */ | /* Don't need to OR flags right now, just a type mark. */ | ||||
| result->flags = LRT_EDGE_FLAG_INTERSECTION; | result->flags = LRT_EDGE_FLAG_INTERSECTION; | ||||
| lineart_prepend_edge_direct(&rb->intersection_lines, result); | lineart_prepend_edge_direct(&rb->intersection_lines, result); | ||||
| int r1, r2, c1, c2, row, col; | int r1, r2, c1, c2, row, col; | ||||
| if (lineart_get_edge_bounding_areas(rb, result, &r1, &r2, &c1, &c2)) { | if (lineart_get_edge_bounding_areas(rb, result, &r1, &r2, &c1, &c2)) { | ||||
| for (row = r1; row != r2 + 1; row++) { | for (row = r1; row != r2 + 1; row++) { | ||||
| for (col = c1; col != c2 + 1; col++) { | for (col = c1; col != c2 + 1; col++) { | ||||
| lineart_bounding_area_link_line( | lineart_bounding_area_link_line( | ||||
| rb, &rb->initial_bounding_areas[row * LRT_BA_ROWS + col], result); | rb, &rb->initial_bounding_areas[row * LRT_BA_ROWS + col], result); | ||||
| Context not available. | |||||
| * so the span for each initial tile is double of that in the (0,1) range. */ | * so the span for each initial tile is double of that in the (0,1) range. */ | ||||
| double span_w = (double)1 / sp_w * 2.0; | double span_w = (double)1 / sp_w * 2.0; | ||||
| double span_h = (double)1 / sp_h * 2.0; | double span_h = (double)1 / sp_h * 2.0; | ||||
| rb->tile_count_x = sp_w; | rb->tile_count_x = sp_w; | ||||
| rb->tile_count_y = sp_h; | rb->tile_count_y = sp_h; | ||||
| rb->width_per_tile = span_w; | rb->width_per_tile = span_w; | ||||
| rb->height_per_tile = span_h; | rb->height_per_tile = span_h; | ||||
| rb->bounding_area_count = sp_w * sp_h; | rb->bounding_area_count = sp_w * sp_h; | ||||
| rb->initial_bounding_areas = lineart_mem_aquire( | rb->initial_bounding_areas = lineart_mem_acquire( | ||||
| &rb->render_data_pool, sizeof(LineartBoundingArea) * rb->bounding_area_count); | &rb->render_data_pool, sizeof(LineartBoundingArea) * rb->bounding_area_count); | ||||
| /* Initialize tiles. */ | /* Initialize tiles. */ | ||||
| for (row = 0; row < sp_h; row++) { | for (row = 0; row < sp_h; row++) { | ||||
| for (col = 0; col < sp_w; col++) { | for (col = 0; col < sp_w; col++) { | ||||
| ba = &rb->initial_bounding_areas[row * LRT_BA_ROWS + col]; | ba = &rb->initial_bounding_areas[row * LRT_BA_ROWS + col]; | ||||
| /* Set the four direction limits. */ | /* Set the four direction limits. */ | ||||
| ba->l = span_w * col - 1.0; | ba->l = span_w * col - 1.0; | ||||
| ba->r = (col == sp_w - 1) ? 1.0 : (span_w * (col + 1) - 1.0); | ba->r = (col == sp_w - 1) ? 1.0 : (span_w * (col + 1) - 1.0); | ||||
| Context not available. | |||||
| BLI_listbase_clear(&root->bp); | BLI_listbase_clear(&root->bp); | ||||
| } | } | ||||
| /** | /** | ||||
| * Subdivide a tile after one tile contains too many triangles. | * Subdivide a tile after one tile contains too many triangles. | ||||
| */ | */ | ||||
| static void lineart_bounding_area_split(LineartRenderBuffer *rb, | static void lineart_bounding_area_split(LineartRenderBuffer *rb, | ||||
| LineartBoundingArea *root, | LineartBoundingArea *root, | ||||
| int recursive_level) | int recursive_level) | ||||
| { | { | ||||
| LineartBoundingArea *ba = lineart_mem_aquire(&rb->render_data_pool, | LineartBoundingArea *ba = lineart_mem_acquire(&rb->render_data_pool, | ||||
| sizeof(LineartBoundingArea) * 4); | sizeof(LineartBoundingArea) * 4); | ||||
| LineartTriangle *rt; | LineartTriangle *rt; | ||||
| LineartEdge *e; | LineartEdge *e; | ||||
| ba[0].l = root->cx; | ba[0].l = root->cx; | ||||
| ba[0].r = root->r; | ba[0].r = root->r; | ||||
| ba[0].u = root->u; | ba[0].u = root->u; | ||||
| ba[0].b = root->cy; | ba[0].b = root->cy; | ||||
| ba[0].cx = (ba[0].l + ba[0].r) / 2; | ba[0].cx = (ba[0].l + ba[0].r) / 2; | ||||
| ba[0].cy = (ba[0].u + ba[0].b) / 2; | ba[0].cy = (ba[0].u + ba[0].b) / 2; | ||||
| Context not available. | |||||