Walters.Robert Posted October 28, 2019 Share Posted October 28, 2019 I'm trying to move a node from a text file for play-back. I was successful a while back via UnigineScript but would like to migrate the code to pure C++. The data is formatted as follows (space delimited): TIME POSXI POSYI POSZI PHI THETA PSI 0 4.50E+03 1.50E+03 -3.00E+02 -1.78E-02 4.92E-02 3.14E+00 6.49E-03 4.50E+03 1.50E+03 -3.00E+02 -1.78E-02 4.92E-02 3.14E+00 1.30E-02 4.50E+03 1.50E+03 -3.00E+02 -1.78E-02 4.92E-02 3.14E+00 1.95E-02 4.50E+03 1.50E+03 -3.00E+02 -1.78E-02 4.92E-02 3.14E+00 2.60E-02 4.50E+03 1.50E+03 -3.00E+02 -1.78E-02 4.92E-02 3.14E+00 3.25E-02 4.50E+03 1.50E+03 -3.00E+02 -1.78E-02 4.92E-02 3.14E+00 3.90E-02 4.50E+03 1.50E+03 -3.00E+02 -1.78E-02 4.92E-02 3.14E+00 4.55E-02 4.50E+03 1.50E+03 -3.00E+02 -1.78E-02 4.92E-02 3.14E+00 5.19E-02 4.50E+03 1.50E+03 -3.00E+02 -1.78E-02 4.92E-02 3.14E+00 5.84E-02 4.50E+03 1.50E+03 -3.00E+02 -1.78E-02 4.92E-02 3.14E+00 Here is my code: FilePtr file = File::create(); int AppWorldLogic::init() { // init systems, do some optimizations for IG Game::get()->setEnabled(1); Physics::get()->setEnabled(0); Render::get()->setMotionBlur(0); Render::get()->setLightsLensFlares(0); file->open("file.txt", "r"); Log::message("The file size is: %i bytes",file->getSize()); return 1; } int AppWorldLogic::update() { if (file->eof()) { file->seekSet(0); } String fileLine = file->readLine(); Log::message("line value: %s at position %i \n", fileLine, file->tell()); file->seekCur(1); return 1; } int AppWorldLogic::render() { return 1; } int AppWorldLogic::flush() { return 1; } int AppWorldLogic::shutdown() { file->close(); return 1; } Unfortunately, while similar code works in Unigine Script I get the following from the above C++ code: 19:38:27 line value: ~ at position 2096 19:38:27 line value: ~ at position 2991 19:38:27 line value: ~ at position 3886 19:38:27 line value: ~ at position 4781 19:38:27 line value: ~ at position 5676 19:38:27 line value: ~ at position 6571 19:38:27 line value: ~ at position 7466 19:38:27 line value: ~ at position 8361 19:38:27 line value: ~ at position 9256 19:38:27 line value: ~ at position 10151 Link to comment
fox Posted October 29, 2019 Share Posted October 29, 2019 Hi Robert, try adding .get() to the fileLine string in your output: Log::message("line value: %s at position %i \n", fileLine.get(), file->tell()); Hope this helps! Thanks! BTW, are you sure you need that "file->seekCur(1);" ? Please note that it skips the first symbol (digit of the TIME column) in each line of your text file. Link to comment
cash-metall Posted October 29, 2019 Share Posted October 29, 2019 also We recommend that you read the entire file in init(), because it is very slow operation. Reading from a file in update() will lead to a huge decrease in performance! Link to comment
Walters.Robert Posted October 30, 2019 Author Share Posted October 30, 2019 Thanks I added the following and as expected it works like a charm: const char* lineValues = fileLine.get(); logging lineValues seems to do the trick. Ultimately I need the values as floats and doubles to pass the position and attitude information to the IG manager to drive my entities. I tried: float stringFloat = atof(lineValues); This pulls the first value but I haven't had any luck getting subsequent values. I've looked through the documentation for parsing strings (substr and split) but I can't seem to find syntax that works. @cash-metall If I read the entire file in init do you recommend that I then write the values to the buffer to be stored in memory while the program steps through them to drive the entities? My data is recorded at 154 hz which is faster than the rendering frame rate I get on my computer. I was planning on using the getFtime() function to figure out how many time steps I should read forward in my arrays. ie. if the rendering time is .03333 seconds (30 hz) then I would step forward 5 places in my array (there will be a slight mis-match in this case as 154/30 isn't a whole number but it should be close enough for my use case). Thanks for the help. Link to comment
cash-metall Posted October 30, 2019 Share Posted October 30, 2019 HDD response time may exceed 15ms. this can lead to spikes. it depends not only on the hard drive, but also on the operating system. however, if you are sure - why not? ))) Unigine::String s = "6.49E-03 4.50E+03 1.50E+03 -3.00E+02 -1.78E-02 4.92E-02 3.14E+00"; auto arr = Unigine::String::split(s, " "); for (int i = 0 ; i < arr.size(); i++) { float f = String::atof(arr[i]); Log::error("value %d is %f\n", i, f); } // ------ output ------ value 0 is 0.006490 value 1 is 4500.000000 value 2 is 1500.000000 value 3 is -300.000000 value 4 is -0.017800 value 5 is 0.049200 value 6 is 3.140000 also You can look at the source NodesInterpolation class (it is used in the syncker plugin). It is designed specifically for the movement nodes on predefined points with timestamp. Link to comment
Recommended Posts