Using AStar in gdnative

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By 3boood_pro

I think there is a problem with the AStar class in gdnative
its not working at all
whenever I use it the godot window crashes immediately

to see what I am talking about:

I am really stuck there…
if anyone know what is the problem let me know

here’s the .cpp file I wrote

#include "gdexample.h"

using namespace godot;
    void GDExample::_register_methods() {
        register_method("_ready", &GDExample::_ready);
        register_method("add_points", &GDExample::add_points);
        register_method("add_point", &GDExample::add_point);
        register_method("create_nav_cube", &GDExample::create_nav_cube);
        register_method("connect_points", &GDExample::connect_points);
        register_method("find_path", &GDExample::find_path);
        register_property<GDExample, float>("grid_step", &GDExample::grid_step, 4.0f);
        register_property<GDExample, bool>("draw_cubes", &GDExample::draw_cubes, false);
    }

    GDExample::GDExample() {
    }

    GDExample::~GDExample() {
        // add your cleanup here
    }

    void GDExample::_init() {
        // initialize any variables here
        grid_step = 4.0f;
		points = {};
        astar = {};
        draw_cubes = false;
    }

    void GDExample::_ready() {
        Array pathables = get_tree()->get_nodes_in_group("pathable");
		//add_points(pathables);
		//connect_points();
		//Godot::print(Variant(astar.get_points().size() + 1));
    }

	void GDExample::add_points(Array pathables)
	{

		int len = pathables.size();

		for (int i = 0; i < len; i++)
		{
			AABB aabb = pathables[i].call("get_transformed_aabb", nullptr, 0);
			Vector3 start_point = aabb.position;

			float x_steps = aabb.size.x / grid_step;
			float y_step = aabb.size.y;
			float z_steps = aabb.size.z / grid_step;

			int additional_z = 0;

			auto parent = pathables[i].call("get_parent", nullptr, 0);

			auto parent_of_parent = parent.call("get_parent", nullptr, 0);

			/*if (parent_of_parent->is_in_group("pathable") == true)
			{
				additional_z = 1;
			}*/
			
			for (int x = 0; x < x_steps + 1;x++)
			{
				for (int z = 0; z < z_steps + additional_z; z++)
				{
					Vector3 next_point = start_point + Vector3(x * grid_step, y_step, z * grid_step);
					add_point(next_point);
				}

			}

		}
	}

	void GDExample::add_point(Vector3 point)
	{
		int id = astar.get_available_point_id();
		if (!points.has(point))
		{
			astar.add_point(id, point);
			points[point] = id;
			create_nav_cube(point);
		}
	}

	void GDExample::create_nav_cube(Vector3 pos)
	{
		if (draw_cubes)
		{
			MeshInstance* cube = new MeshInstance;
			CubeMesh* cubemesh = new CubeMesh;
			cubemesh->set_size(Vector3(0.25, 0.25, 0.25));
			cube->set_mesh(cubemesh);
			this->add_child(cube);
			cube->get_global_transform().set_origin(pos);
		}
	}

	void GDExample::connect_points()
	{
		for (int i = 0; i < points.size(); i++)
		{
			Vector3 pos = points.keys()[i];

			auto search_coords = { -grid_step * 2, -grid_step, 0.0f, grid_step, grid_step * 2 };
			auto search_y_coords = { -grid_step * 2, -grid_step, 0.0f, grid_step, grid_step * 2 };

			for (int x = 0; x < search_coords.size(); x++)
			{
				for (int y = 0; y < search_y_coords.size(); y++)
				{
					for (int z = 0; z < search_coords.size(); z++)
					{
						Vector3 search_offset = Vector3(x, y, z);

						if (search_offset == Vector3(0, 0, 0))
						{
							continue;
						}

						String neighbor = String(pos + search_offset);
						if (points.has(neighbor))
						{
							int current_id = points[points.keys()[i]];
							int neighbor_id = points[neighbor];
							if (!astar.are_points_connected(current_id, neighbor_id))
							{
								astar.connect_points(current_id, neighbor_id);
							}

						}

					}
				}
			}

		}
	}

	PoolVector3Array GDExample::find_path(Vector3 from, Vector3 to)
	{
		auto start_id = astar.get_closest_point(from);
		auto end_id = astar.get_closest_point(to);
		return astar.get_point_path(start_id, end_id);
	}

extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options * o) {
    godot::Godot::gdnative_init(o);
}

extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options * o) {
    godot::Godot::gdnative_terminate(o);
}

extern "C" void GDN_EXPORT godot_nativescript_init(void* handle) {
    godot::Godot::nativescript_init(handle);

    godot::register_class<godot::GDExample>();
}

and here’s the .h file

#pragma once

#ifndef GDEXAMPLE_H
#define GDEXAMPLE_H

#include <Godot.hpp>
#include <Node.hpp>
#include <Spatial.hpp>
#include <AStar.hpp>
#include <SceneTree.hpp>
#include <MeshInstance.hpp>
#include <CubeMesh.hpp>

namespace godot {

    class GDExample : public Spatial {
        GODOT_CLASS(GDExample, Spatial)
        
    private:
        float grid_step;
        Dictionary points;
        AStar astar;
        bool draw_cubes;
    public:
        static void _register_methods();

        GDExample();

        ~GDExample();

        void _init(); // our initializer called by Godot

        void _ready();

        void add_points(Array pathables);

        void add_point(Vector3 point);

        void create_nav_cube(Vector3 pos);

        void connect_points();

        PoolVector3Array find_path(Vector3 from, Vector3 to);
    };

}

#endif
:bust_in_silhouette: Reply From: 3boood_pro

AStar astar; should be Ref<AStar> astar; instead
And inside _init you may do astar.instance(); to create it

Thx Zylann for the Answer :smiley: