# Scale() + tpf?

Hey, I’m following the tutos and i was wondering : “how can you use “tpf” to regulate a scale in the event loop ?”. I’d like to make a cube grow and shrink again and again… here is my code :

[java]//…

if(boolean){

cube.scale(2);

}else{

cube.scale(.5f);

}

if (cpt < 100){

cpt++;

}else{

cpt=0;

}

if(cpt==0){

boolean = !boolean;

}

//…[/java]

The trouble I’m having with this is that the cube pulsates so fast that I can barely see it ! So I guess that “tpf” is the key I just dont know how to use it…

Any ideas ?

Just multiply your values by tpf, so 2tpf .5ftpf etc.

I’ve already tried it… but as a result I just get my cube disappeared.

So raise the multiplier: 200*tpf

Nope I had tried this too but the cube seems not to be in the scene at all even if it was before I use scale on it.

So did you attach it to the root node and add a light if its got a lighted material? Did you read the tutorials at all?

Here is my full code…

[java]package jme3test.helloworld;

import com.jme3.app.SimpleApplication;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.Node;

import com.jme3.scene.shape.Box;

public class HelloLoop extends SimpleApplication {

public static void main(String[] args) {

HelloLoop app = new HelloLoop();

app.start();

}

protected Geometry cubea;

protected Geometry cubeb;

boolean bool = false;

int cpt = 0;

@Override

public void simpleInitApp() {

Node pivot = new Node("pivot");

rootNode.attachChild(pivot);

pivot.setLocalTranslation(1, 1, 1);

// Box a = new Box(Vector3f.ZERO, 1, 1, 1);

// cubea = new Geometry("red cube", a);

// Material mata = new Material(assetManager, "Common/MatDefs/Misc/SolidColor.j3md");

// mata.setColor("m_Color", ColorRGBA.Red);

// cubea.setMaterial(mata);

// pivot.attachChild(cubea);

Box b = new Box(Vector3f.ZERO, 1, 1, 1);

cubeb = new Geometry("blue cube", b);

Material matb = new Material(assetManager, "Common/MatDefs/Misc/SolidColor.j3md");

matb.setColor("m_Color", ColorRGBA.Blue);

cubeb.setMaterial(matb);

rootNode.attachChild(cubeb);

}

@Override

public void simpleUpdate(float tpf) {

// cubea.rotate(0, -2 * tpf, 0);

cubeb.rotate(0, -1 * tpf, 0);

if (bool) {

cubeb.scale(2 * tpf);

} else {

cubeb.scale(.5f * tpf);

}

if (cpt < 10) {

cpt++;

} else {

cpt = 0;

bool = !bool;

}

}

}[/java]

ofc i did what you say. I told you the cube did appears before i use tpf in my scale method, so it obviously comes from this.

s4milli4 said:
Nope I had tried this too but the cube seems not to be in the scene at all even if it was before I use scale on it.

I was reading this like "it was never visible", sorry.
And btw, use something like cpt+=tpf for the counter to make it framerate independent.

So.. for ten frames you half the size of the cube, then the next 10 frames you scale it up again.. Could the problem be that 2*tpf (instead of 2f*tpf) results in an integer and the box is getting too big? Probably that all happens before you properly see the scene.

When you print out your tpf, you will see, it’s a value something around 1/60 to 1/500 (dependent from the framerate).

So you must use some really big numbers or just make it framerate-independent.

I have just tried with 2000ftpf and .0005ftpf (as I’m having a frame rate of 800-1000 → a tpf around 1/800 - 1/1000 then) in order to balance. Still the same problem…

So you do something wrong. Is the cam inside the box maybe.

I would say no, but if the cube does get too big it can turn in my cam being inside the cube, yes.

I think it’s a simple Math-problem with precision:

When you insert

[java]System.out.println(cubeb.getLocalScale());[/java]

at the end of the update-loop, you will see, it goes towards (0.0, 0.0, 0.0). And from zero, it can’t rise again with multiplication, since 0*2000 still is 0.

I get your point but, the cube is not supposed to reach (0.0, 0.0, 0.0) as

I only divide his size… For instance if you divide 1 by 2 again and again you’ll reach something close to 0 (i.e. 1/(2222222…) ) but you’ll never reach the exact 0 value (unless there is some approach values in there what Im not sure of…).

Moreover, im using the following proportions :

grow → I multiply by 1.1

shrink → I multiply by .91

Or, to maintain a constant pulse I should shrink using 1/1.1=0.9090909… So in the end I make the cube grow more than I make it shrink (sry for my english in the last sentence 'O_o I’m not sure I make you understand my point). So if I start by making my cube growing, it should keep a reasonable scale (I guess).

but the number gets so small, that float can’t save it anymore and makes 0 out of it

Yeah, in computers everything is quantized as opposed to the real world.

@s4milli4

Turn cpt into a float and use this variable to keep the current total scale variable, that way you keep way more control on what you are trying to do.

For each update, either increase or decrease this variable by tpf, then do not use cubeb.scale but instead go with cubeb.setLocalScale(cpt).

Try this piece after changing the int to a float:

[java] if (cpt >= 1.5f) // max size

bool = false;

else if (cpt <= 0.5f) // min size

bool = true;

if (bool) // still allowed to grow

cpt += tpf;

else // shrinking

cpt -= tpf;

cubeb.setLocalScale(cpt);[/java]

Instead of the hassle of making these if statements you could as wel go with a sine function while simply increasing cpt every update, this also gets rid of the harsh changes at the max and min sizes:

[java] cpt += tpf;

cubeb.setLocalScale(FastMath.sin(cpt * 2)*0.5f + 1.5f);[/java]

Hope that clears things up for you

Exactly what i wanted (even if i dont get everything yet O_o). Thx !

Ok i get it now… I’ll remember the sin tip ;), very useful !