Jump to content

Move node from Text File via C++


photo

Recommended Posts

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

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

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

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

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
×
×
  • Create New...