Your professor is not correct about memory sharing. I'd have to look at the whole code to be able to tell you the exact cause for sure, but I know from writing Cloth implementations and the springs in the ChaseCamera that implementing Springs using a literal implementation of hooke's equation is unstable (springs in general are tricky.) The problem usually lies in your "dt" variable fluctuating based on what the cpu is doing in the background. If dt is ever exceptionally large, your v_alt and s_alt values will be unusally low or high and it will carry that value to the next loop, compounding the problem over and over until it is NaN (ie. the value was too big - either in the positive or negative direction - to represent as a float in Java.) It doesn't take very many loops for that to happen.
One thing you might do to lengthen the time your sim can run is instead of:
trans = new Vector3f(0,s,0);
do this to prevent lots of object creation (less gc means a smoother cpu run):
trans.y = s;
Unfortunately, the only real way to keep the NaN from appearing is to either check the numbers as they are generated and keep them in a "real" range or change the implementation to not reuse the old velocity and acceleration (you could use position to derive those values) Both have some issues still.
Another thing you could do to keep your simulation running is detect NaN and reset your simulation to 0.
This means your calculated result get's placed in a new Vector every time. Less than ideal, but there is absolutly no way jME can influence the result of your calculations. Not sure what your professor is saying but it sounds like he does not understandJava. When a primitive variable (such as int, float, double, etc.) is assigned to another variable, always a copy is made.
So you could do :
myBox.getLocalTranslation().y = (float)s;
And even then in no way could anything in the Vector3f class influence s. The error must be in your calculations somewhere.
what do you mean by "but the simpleUpdate method seem not to be called in frequent way"?
when running calcEuler from the simpleUpdate method the box seems to stand still, just because calcEuler is called alot less frequently than when running through your thread. your thread doesnt do any Thread.yield or Thread.sleep so calcEuler runs thousands of times on every jme update, so the box has come to rest before showing up in 3d…
using a higher "dt" will show some action again, but also give higher instability offcourse…i didn't get any NaN's but i suspect it is either instability explosion or a threading issue.
what do you mean by "but the simpleUpdate method seem not to be called in frequent way"?
With opengl4java i can set up how often per second the display-method is called.
How often JME calls the simpleUpdate() method? It seems to to be frequently, i.e. ~60 times per second.
when running calcEuler from the simpleUpdate method the box seems to stand still, just because calcEuler is called alot less frequently than when running through your thread. your thread doesnt do any Thread.yield or Thread.sleep so calcEuler runs thousands of times on every jme update, so the box has come to rest before showing up in 3d...
dt must be very small to get good results. if it's about 0,001 the result of the calculation would be very wrong after a few moments.
So i need to calc with a small dt and many iterations/seconds ...
Using a sleep(1) in the thread it's too slow.
using a higher "dt" will show some action again, but also give higher instability offcourse...i didn't get any NaN's but i suspect it is either instability explosion or a threading issue.
hmm, you don't get an NaN ?? Hmm, maybe it's a hardware/driver issue ?! I will try it on different pc's ...
I currently testing the same program with another computer. runs fine without any NaN … hmm, okay. So it's not the program's fault, and of course not mine
On my machines i only get this error with my laptop. IBm Thinkpad R51e, 1,7Ghz Dothan-Centrino, 1GB RAM, Windows Xp Prof., Java 5 Update 7, ATI Radeon 9000 …
Don't know what's wrong with this machine… I will try some things like diabling powermanagement of the graphics card and so on …
thanks so far to all the people for testing the code…
At university i have to use the cisco cpn client software to get connected to the internet and the university net.
If I am connected with the vpn i get NaN's after a few seconds.
I disconnected the vpn and guess what? The programs runs over minutes without any NaN …
Currently I'm trying to reproduce this problem on another pc …
…working…
And guess what? Now, with the installed and connected cisco vpn client on my second computer there are also NaN's …
This is crazy, isn't it?
Maybe the Devs of JME can comfirm this. If it's true that the Cisco VPN Client cann cause such problem in alle JME / OpenGL4Java Programs it should be mentioned somewhere… maybe wiki or faq …
why don't you iterate your calcEuler yourself in the simpleUpdate method(so you won't have to go through the fuzz with threads *s* ;) )
something like this perhaps(just writing without validating anything)
private final int calcsPerSecond = 1000000;
private final float counterThreshold = 1.0f / calcsPerSecond;
private float counter = 0;
protected void simpleUpdate() {
counter += tpf;
while (counter > counterThreshold) {
calcEuler();
counter -= counterThreshold;
}
boxEuler.getLocalTranslation().y = (float) s;
}
That's the point... simpleUpdate isn't running that fast as my external thread runs... If I try so call the calcEuler method in simleUpdate it's running veeeeeeeeeery slow.
I don't know why... But now i solved the problem (see my post with the cisco vpn client).
are you saying that the method-call to calcEuler is slow when calling it from simpleUpdate??? sounds like something is really messed up on that university-comp
are you saying that the method-call to calcEuler is slow when calling it from simpleUpdate??? sounds like something is really messed up on that university-comp :)
Ok, my fault. it's not slow... It seems that simpleUpdate ist not called fast enough, and so calcEuler isn't called often enough...
If I put a counter in simpleUpdate, after a few seconds the counter is over 5000 ... But for using a "dt" that is about 0,0000001 the calcEuler must be called more often than simpleUpdate is called. And the first working solution was the idea with the 2nd thread that calls calcEuler as fast as java can.
btw: It's not a university-comp... It's my personal laptop... And all other things are running fine.. And now, with VPN disconnected my simulation-program is also running fine...
did you read the code i posted at all?
if simple update is called once a second for example, calcEuler will be called "calcsPerSecond" times in that update...
Sorry, I was too fast. Didn't see that.
But yes, that would be the another solution. Calling calcEuler many many times and then set the new position.
But with your solution it's still not working with the vpn connected... :) Cisco VPN s*cks :)
- Alex