Pulsating cube in the HelloLoop tutorial

Hey there, jMonkeyEngine community,

I’m an absolute beginner to this engine and just started to use it for a game I want to create for my bachelor thesis. I’m currently doing all the tutorials and encountered the first problem in the fourth tutorial about the simpleUpdate function.

The third exercise of this tutorial tells me to create a pulsating cube. That’s not difficult, of course, and it works, but ONLY if I don’t use a value lower than 0.8 in the following code snippet:

[java]Vector3f player3Scale = player3.getLocalScale();

    if(player3Scale.getX() > 1.0f) {
        grows = false;
    } else if(player3Scale.getX() < 0.8f) {
        grows = true;
    }
    
    if(grows) {
        player3.scale(1 + (3f * tpf));
    } else {
        player3.scale(1 - (3f * tpf));
    }[/java]

If I change the 0.8 to a 0.7, for example, the cube starts growing indefinitely, caused by the .getX() values dropping below 0. The console output (.getX() values) looks like the following:

[java]1.0
0.7297375
-0.11936189
-0.12496533
-0.13102396
-0.13754459
-0.14441627
-0.15166436
-0.15920757
-0.16718069
-0.17555684[/java]

Can someone tell me why that’s the case - whether I’m missing something or it’s a bug and how I can fix it?

Really strange, it should work, i tested it my computer also it worked.
did you try to delete and create a new main class with the same code?

Tried it, still doesn’t work. It’s strange, indeed. I even commented out all the other geometries in the scene - still the same problem…

I’m suspicious because the code you posted is clearly different than the code you run because the code you run has a debug println in it.

Paste the actual code… in case there is some significant typo that was not included in the transcription.

The only difference is that println, actually. I just excluded it because it’s not important.

@@MateStrysewske said: The only difference is that println, actually. I just excluded it because it's not important.

Oh, cool… then it must be running just fine. :wink: I wonder what else was excluded that wasn’t important. Seriously, though…

One thing to note: scale() is relative. So if scale ever goes to 0 then it will stay 0 forever. If it ever goes negative then it will stay negative forever. So perhaps when you run at the lower threshold it goes negative once and then stays there.

I guess it’s a nice example but the code is not very robust in the face of large tpf (caused by extremely slow frame rates).

Well, instead of saying “it’s not important”, let’s say it’s completely irrelevant for the functionality of the code. Like I said, it’s the only line that I excluded. :wink:

That’s a good answer, thank you! So it seems like the update cycle isn’t called often enough to prevent the value from dropping below 0 and therefore the cube grows indefinitely. Would you suggest to use “setLocalScale” then?

Or use math that won’t go below 0 if tpf is larger than 0.33 for one frame.

Really, for pulsating I might have used setLocalScale((1 + FastMath.sin(time)) * 0.5f) or something.

Thank you, that helps a lot. I don’t really understand why scale() behaves like that, but it’s good to know that it does and that I should use other stuff instead. :slight_smile:

@@MateStrysewske said: Thank you, that helps a lot. I don't really understand why scale() behaves like that, but it's good to know that it does and that I should use other stuff instead. :)

If you have something 5 units wide (whatever the current scale) and you call scale(0.5) you’d expect it to be 2.5 units wide. Therefore, for the method to have any meaning, if you call scale(0.5) again then it should end up as 1.25 units wide and so on.

If you call scale(-1) then you invert all axes. scale(), move(), and rotate() are all relative. Convenient, but I rarely ever use them in a real game.

Makes sense. Thanks again!