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);
}
Example #2
0
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);
}
Example #3
0
/**
 * @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;
}
Example #4
0
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;
}