void stalker_movement_manager_obstacles::move_along_path_impl (CPHMovementControl *movement_control, Fvector &dest_position, float time_delta) { #ifndef MASTER_GOLD if (psAI_Flags.test(aiObstaclesAvoidingStatic)) #endif // MASTER_GOLD { m_dynamic_obstacles.update (); if (!m_dynamic_obstacles.movement_enabled()) { float desirable_speed = old_desirable_speed(); set_desirable_speed (0.f); inherited::move_along_path (movement_control, dest_position, time_delta); set_desirable_speed (desirable_speed); return; } } m_static_obstacles.update (); if ( #ifndef MASTER_GOLD (!psAI_Flags.test(aiObstaclesAvoidingStatic) && m_dynamic_obstacles.need_path_to_rebuild() ) || #endif // MASTER_GOLD m_static_obstacles.need_path_to_rebuild()) rebuild_path (); inherited::move_along_path (movement_control, dest_position, time_delta); }
char *path_simplifier(char *path) { int i; int len; t_path *path_list; i = 0; path_list = NULL; while (path[i]) { len = 0; while (path[i] && path[i] == '/') i++; while (path[i + len] && path[i + len] != '/') len++; add_path(&path_list, ft_strsub(path, i, len)); i += len; } remove_dot(&path_list); remove_dotdot(&path_list, path_list); free(path); path = rebuild_path(path_list); free_pathlist(path_list); return (path); }
/** * @brief Tries to find a path between the source point and the target point. * @return the path found, or an empty string if no path was found * (because there is no path or the target is too far) */ std::string PathFinding::compute_path() { //std::cout << "will compute a path from " << source_entity.get_top_left_x() << "," // << source_entity.get_top_left_y() << " to " << target_entity.get_top_left_x() << "," // << target_entity.get_top_left_y() << std::endl; Rectangle source = source_entity.get_bounding_box(); Rectangle target = target_entity.get_bounding_box(); target.add_x(4); target.add_x(-target.get_x() % 8); target.add_y(4); target.add_y(-target.get_y() % 8); int target_index = get_square_index(target); Debug::check_assertion(target.get_x() % 8 == 0 && target.get_y() % 8 == 0, "Could not snap the target to the map grid"); int total_mdistance = get_manhattan_distance(source, target); if (total_mdistance > 200 || target_entity.get_layer() != source_entity.get_layer()) { //std::cout << "too far, not computing a path\n"; return ""; // too far to compute a path } std::string path = ""; Node starting_node; int index = get_square_index(source); starting_node.location = source; starting_node.index = index; starting_node.previous_cost = 0; starting_node.heuristic = total_mdistance; starting_node.total_cost = total_mdistance; starting_node.direction = ' '; starting_node.parent_index = -1; open_list[index] = starting_node; open_list_indices.push_front(index); bool finished = false; while (!finished) { // pick the node with the lowest total cost in the open list int index = open_list_indices.front(); Node *current_node = &open_list[index]; open_list_indices.pop_front(); closed_list[index] = *current_node; open_list.erase(index); current_node = &closed_list[index]; //std::cout << System::now() << " picking the lowest cost node in the open list (" // << (open_list_indices.size() + 1) << " elements): " // << current_node->location << ", index = " << current_node->index // << ", cost = " << current_node->previous_cost << " + " << current_node->heuristic << "\n"; if (index == target_index) { //std::cout << "target node was added to the closed list\n"; finished = true; path = rebuild_path(current_node); //std::cout << "rebuild done\n"; } else { // look at the accessible nodes from it //std::cout << System::now() << " looking for accessible states\n"; for (int i = 0; i < 8; i++) { Node new_node; int immediate_cost = (i & 1) ? 11 : 8; new_node.previous_cost = current_node->previous_cost + immediate_cost; new_node.location = current_node->location; new_node.location.add_xy(neighbours_locations[i]); new_node.index = get_square_index(new_node.location); //std::cout << " node in direction " << i << ": index = " << new_node.index << std::endl; bool in_closed_list = (closed_list.find(new_node.index) != closed_list.end()); if (!in_closed_list && get_manhattan_distance(new_node.location, target) < 200 && is_node_transition_valid(*current_node, i)) { //std::cout << " node in direction " << i << " is not in the closed list\n"; // not in the closed list: look in the open list bool in_open_list = open_list.find(new_node.index) != open_list.end(); if (!in_open_list) { // not in the open list: add it new_node.heuristic = get_manhattan_distance(new_node.location, target); new_node.total_cost = new_node.previous_cost + new_node.heuristic; new_node.parent_index = index; new_node.direction = '0' + i; open_list[new_node.index] = new_node; add_index_sorted(&open_list[new_node.index]); //std::cout << " node in direction " << i << " is not in the open list, adding it with cost " // << new_node.previous_cost << " (" << current_node->previous_cost << " + " // << immediate_cost << ") + " << new_node.heuristic << " and parent " << new_node.parent_index << "\n"; } else { //std::cout << " node in direction " << i << " is already in the open list\n"; Node *existing_node = &open_list[new_node.index]; // already in the open list: see if the current path is better if (new_node.previous_cost < existing_node->previous_cost) { existing_node->previous_cost = new_node.previous_cost; existing_node->total_cost = existing_node->previous_cost + existing_node->heuristic; existing_node->parent_index = index; open_list_indices.sort(); } } } else { //std::cout << "skipping node in direction " << i << ": already in closed list = " // << in_closed_list << ", too far from target = " // << (get_manhattan_distance(new_node.location, target) >= 200) << ", invalid transition = " // << (!is_node_transition_valid(*current_node, i)) << std::endl; } } if (open_list_indices.empty()) { finished = true; } } } //std::cout << "path found: " << path << ", open nodes: " << open_list.size() << ", closed nodes: " << closed_list.size() << std::endl; return path; }
static void svg_drawable_traverse(GF_Node *node, void *rs, Bool is_destroy, void (*rebuild_path)(GF_Node *, Drawable *, SVGAllAttributes *), Bool is_svg_rect, Bool is_svg_path) { GF_Matrix2D backup_matrix; GF_Matrix mx_3d; DrawableContext *ctx; SVGPropertiesPointers backup_props; u32 backup_flags; Drawable *drawable = (Drawable *)gf_node_get_private(node); GF_TraverseState *tr_state = (GF_TraverseState *)rs; SVGAllAttributes all_atts; if (is_destroy) { #if USE_GF_PATH /* The path is the same as the one in the SVG node, don't delete it here */ if (is_svg_path) drawable->path = NULL; #endif drawable_node_del(node); return; } assert(tr_state->traversing_mode!=TRAVERSE_DRAW_2D); if (tr_state->traversing_mode==TRAVERSE_PICK) { svg_drawable_pick(node, drawable, tr_state); return; } /*flatten attributes and apply animations + inheritance*/ gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); if (!compositor_svg_traverse_base(node, &all_atts, (GF_TraverseState *)rs, &backup_props, &backup_flags)) return; /* Recreates the path (i.e the shape) only if the node is dirty */ if (gf_node_dirty_get(node) & GF_SG_SVG_GEOMETRY_DIRTY) { /*the rebuild function is responsible for cleaning the path*/ rebuild_path(node, drawable, &all_atts); gf_node_dirty_clear(node, GF_SG_SVG_GEOMETRY_DIRTY); drawable_mark_modified(drawable, tr_state); } if (drawable->path) { if (*(tr_state->svg_props->fill_rule)==GF_PATH_FILL_ZERO_NONZERO) { if (!(drawable->path->flags & GF_PATH_FILL_ZERO_NONZERO)) { drawable->path->flags |= GF_PATH_FILL_ZERO_NONZERO; drawable_mark_modified(drawable, tr_state); } } else { if (drawable->path->flags & GF_PATH_FILL_ZERO_NONZERO) { drawable->path->flags &= ~GF_PATH_FILL_ZERO_NONZERO; drawable_mark_modified(drawable, tr_state); } } } if (tr_state->traversing_mode == TRAVERSE_GET_BOUNDS) { if (! compositor_svg_is_display_off(tr_state->svg_props)) { DrawAspect2D asp; gf_path_get_bounds(drawable->path, &tr_state->bounds); if (!tr_state->ignore_strike) { memset(&asp, 0, sizeof(DrawAspect2D)); drawable_get_aspect_2d_svg(node, &asp, tr_state); if (asp.pen_props.width) { StrikeInfo2D *si = drawable_get_strikeinfo(tr_state->visual->compositor, drawable, &asp, NULL, drawable->path, 0, NULL); if (si && si->outline) { gf_path_get_bounds(si->outline, &tr_state->bounds); } } } compositor_svg_apply_local_transformation(tr_state, &all_atts, &backup_matrix, NULL); if (!tr_state->abort_bounds_traverse) gf_mx2d_apply_rect(&tr_state->transform, &tr_state->bounds); gf_sc_get_nodes_bounds(node, NULL, tr_state, NULL); compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, NULL); } } else if (tr_state->traversing_mode == TRAVERSE_SORT) { /*reset our flags - this may break reuse of nodes and change-detection in dirty-rect algo */ gf_node_dirty_clear(node, 0); if (!compositor_svg_is_display_off(tr_state->svg_props) && ( *(tr_state->svg_props->visibility) != SVG_VISIBILITY_HIDDEN) ) { compositor_svg_apply_local_transformation(tr_state, &all_atts, &backup_matrix, &mx_3d); ctx = drawable_init_context_svg(drawable, tr_state); if (ctx) { if (is_svg_rect) { if (ctx->aspect.fill_texture && ctx->aspect.fill_texture->transparent) {} else if (GF_COL_A(ctx->aspect.fill_color) != 0xFF) {} else if (ctx->transform.m[1] || ctx->transform.m[3]) {} else { ctx->flags &= ~CTX_IS_TRANSPARENT; if (!ctx->aspect.pen_props.width) ctx->flags |= CTX_NO_ANTIALIAS; } } if (all_atts.pathLength && all_atts.pathLength->type==SVG_NUMBER_VALUE) ctx->aspect.pen_props.path_length = all_atts.pathLength->value; #ifndef GPAC_DISABLE_3D if (tr_state->visual->type_3d) { if (!drawable->mesh) { drawable->mesh = new_mesh(); if (drawable->path) mesh_from_path(drawable->mesh, drawable->path); } visual_3d_draw_from_context(ctx, tr_state); ctx->drawable = NULL; } else #endif { drawable_finalize_sort(ctx, tr_state, NULL); } } compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d); } } memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers)); tr_state->svg_flags = backup_flags; }