![]() |
Attention | Topic was automatically imported from the old Question2Answer platform. |
![]() |
Asked By | humbletang |
I’m a little bit confused because it seems like the property changes to a node made in the editor seem to not appear until the process
step, instead of ready
. Am I missing something?
It seems like this is related to Inconsistent behaviour of setup methods between GDScript and GDNative (C++) - values and default values of properties · Issue #26237 · godotengine/godot · GitHub and Undocumented unexpected properties behavior · Issue #301 · godotengine/godot-cpp · GitHub. The difference is that I’m just trying to make use of the updated property once it’s changed from the default. I don’t mind having to specify the default multiple places. It just seems like the property changes it’s value somewhere between my _ready
and the subsequent _process
calls…
Imgur: The magic of the Internet <— the initial property
https://i.imgur.com/juwYZjI.png ← screenshot showing modified property in editor
gdexample.h
#ifndef GDEXAMPLE_H
#define GDEXAMPLE_H
#include <Godot.hpp>
#include <File.hpp>
#include <vector>
#include <chrono>
#include <iostream>
#include <ResourceLoader.hpp>
#include <Material.hpp>
#include <fstream>
#include <String.hpp>
#include <OS.hpp>
#include <Spatial.hpp>
#include <ArrayMesh.hpp>
#include <MeshInstance.hpp>
namespace godot {
class GDExample : public Spatial {
GODOT_CLASS(GDExample, Spatial)
private:
float speed;
float amplitude;
float time_passed;
float time_emit;
String file_pth;
public:
static void _register_methods();
GDExample();
~GDExample();
void _init(); // our initializer called by Godot
void _ready();
void _process(float delta);
void set_speed(float p_speed);
float get_speed();
};
}
#endif
gdexample.cpp
#include "gdexample.h"
using namespace godot;
using namespace std;
void GDExample::_register_methods() {
register_method("_process", &GDExample::_process);
register_property<GDExample, float>("amplitude", &GDExample::amplitude, 10.0);
register_property<GDExample, float>("speed", &GDExample::set_speed, &GDExample::get_speed, 1.0);
register_property<GDExample, String>("file_pth", &GDExample::file_pth, "./plant.ply");
register_signal<GDExample>((char *)"position_changed", "node", GODOT_VARIANT_TYPE_OBJECT, "new_pos", GODOT_VARIANT_TYPE_VECTOR2);
}
GDExample::GDExample() {
}
GDExample::~GDExample() {
// add your cleanup here
}
void GDExample::_init() {
Godot::print("_init");
// for some reason the tutorial initializes values here, which seems like it overrides the values set in the property window of the editor.
time_passed = 0.0;
amplitude = 10.0;
speed = 10.0;
file_pth = "./plant.ply";
// but if I don't set them here then they remain un initialized. How do I get the values typed into the property window to get used for my class members?
this->_ready();
}
struct point {
double x;
double z;
double y;
unsigned char r;
unsigned char g;
unsigned char b;
};
void GDExample::_ready() {
auto mat = ResourceLoader::get_singleton()->load("res://mat.tres");
Godot::print("_ready");
Godot::print(amplitude);
// Simple test code adapted from GDscript docs to native C++
// Might leak if called repeatedly (not sure how that's handled),
// but it gets a triangle on the screen.
PoolVector3Array vertices;
std::chrono::steady_clock::time_point beg = std::chrono::steady_clock::now();
auto mySimpleMesh = ArrayMesh::_new();
godot::Array arrays; // kind of a struct-of-arrays approach to vertex attributes (or array of arrays with enumerated keys)
// Vertex colors don't show correctly, probably because there's no material/skin yet.
PoolColorArray colors; // optional...
//
// read file, and populate the verts and colors
// see if using the gd FILe type is faster than some c++ method
//auto f = File::_new();
ifstream f (file_pth.alloc_c_string(),ios::binary);
cout << amplitude << endl;
Godot::print("loading file");
// **** this prints the default ./plant.ply ***
Godot::print(file_pth);
string s;
for (int i = 0;i< 11;i++ ) {
getline(f,s);
}
int fbeg = int(f.tellg());
f.seekg(0,ios::end);
int fend = int(f.tellg());
f.seekg(fbeg,ios::beg);
//vector<char> buf(fend-fbeg);
//f.read(buf.data(),fend-fbeg);
// figure out from the size of the data how many points we can have and print that
int correct_size = 27;
int buf_size = fend-fbeg;
int size = (buf_size)/correct_size;
cout << buf_size << endl;
cout << size << endl;
// convert the entire thing into a vector of structs that we can iterate over
vector<point *> points;
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
vector<char> buf(fend-fbeg);
f.read(buf.data(),fend-fbeg);
for (int i =0; i < size;i++) {
//cout << i << endl;
// read 27 bytes and assign them to the parts of a point that matter
point * p = reinterpret_cast<point *>(buf.data()+i*27);
//cout << p->x << endl;
//cout << p->y << endl;
//cout << p->z << endl;
//cout << int(p->r) << endl;
//cout << int(p->g) << endl;
//cout << int(p->b) << endl;
//points.push_back(p);
vertices.append(Vector3(p->x - 409001,p->y- 0.957346,p->z- 3660087.5));
//vertices.append(Vector3(p->x ,p->y,p->z));
colors.append(Color(float(p->r)/256.0,float(p->g)/256.0,float(p->b)/256.0));
}
Godot::print(vertices[0]);
cout << vertices.size()<< endl;
arrays.resize(ArrayMesh::ARRAY_MAX);
arrays[ArrayMesh::ARRAY_VERTEX] = vertices; // required
arrays[ArrayMesh::ARRAY_COLOR] = colors;
mySimpleMesh->add_surface_from_arrays(Mesh::PRIMITIVE_POINTS, arrays);
mySimpleMesh->surface_set_material(0,mat);
// pMeshInstance = new MeshInstance; // NO! BAD! Will crash the game!
auto mySimpleMeshInstance = MeshInstance::_new(); // This is how we do things here.
mySimpleMeshInstance->set_mesh(mySimpleMesh);
add_child(mySimpleMeshInstance);
auto bb = mySimpleMeshInstance->get_aabb();
//translate(-bb.position);
//auto cam = get_node("../Camera");
Godot::print(bb);
//cam->translate( q
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << "[ms]" << std::endl;
}
void GDExample::_process(float delta) {
// ***** this prints the modified file_pth property of ./plants2.ply
Godot::print(file_pth);
// Godot::print("_process");
//
// time_passed += speed * delta;
//
// Vector3 new_position = Vector3(
// amplitude + (amplitude * sin(time_passed * 20.0)),
// 0,
// amplitude + (amplitude * cos(time_passed * 15.0))
// );
//
// set_global_translation(new_position);
//
// time_emit += delta;
// if (time_emit > 1.0) {
// emit_signal("position_changed", this, new_position);
//
// time_emit = 0.0;
// }
}
void GDExample::set_speed(float p_speed) {
speed = p_speed;
}
float GDExample::get_speed() {
return speed;
}
Still love to know about how to do this, but I have a work around. Take the existing _ready
function and make that something called makecloud
and then add a getter and setter to the property for file_pth
. Then inside the setter for the file_pth
I can invoke the makecloud
and that will mean I don’t have to add logic for loading the cloud to process.
humbletang | 2023-01-06 23:36