Vector operations without creation of new objects

Hi,

I’m just starting to learn jMonkey, I’m trying to simulate dynamics of particles by simple integration of Newton equations



like

v += (F/m).dt

r += v.dt

… where v,r,F are vectors



if I use Vector3f class math, is it possible to do such operations without creation of temporary vector objects? Because I guess allocation of new object take time and can cause insufficient memory overflow.



I tried to use scaleAdd(float scalar, Vector3f add), however it looks like that

v.scaleAdd(dt/m, F)

does

v = v*(dt/m) + F

rather than

v = v + F*(dt/m)

There are local version of most (if not all) vector methods that store the result in the vector itself, e.g. Vector3f.addLocal(Vector3f) rather than Vector3f.add(Vector3f).

Vector3f.scaleAdd(float, Vector3f), however, is local already.

To do the calculation v = v + F*(dt/m), where v and F are vectors and (dt/m) is a scalar, you could do v.addLocal(F.multLocal(dt/m)).

Yes, I know about “local” versions of functions (I read the javadoc of Vectror3f class)



v.addLocal(F.multLocal(dt/m));



ok, the trouble is that I want conserve vector F for other computations.

also when I do

r += v.dt

I can’t use

r.addLocal(v.multLocal( dt ));

because I need to conserve v for the next iteration of the dynamics.



sure it would be possible something like this

r.addLocal(v.multLocal( dt )); // first multiply

v.multLocal( 1.0/dt )); // divide after

but it’s not very nice solution



I know, this is not really serious troubleshooting, I just ask how it’s supposed to do the most elegant way (most efficient end numerically precise, and to keep code readable).

you can use TempVars.

It’s a JME Util class that reuse the variables.



usage is

[java]

TempVars vars = TempVars.get();

Vector3f v = vars.vect1;



do your stuff;



vars.release(); //don’t forget to release the vars

[/java]

You will have to clone it at one point. You can also use TempVars or create final Vector3f objects and just set the values on them, if you do not want to create new vector objects all the time. Just re-use some existing ones.

Really, JME misses a decent add and multiple method on Vector. There is the very strange scaled vector add one that seems three kinds of backwards to me but not a simple addScaledVectorLocal() which is an extremely common operation to want to do.



I ended up just writing a util method that operates directly on the fields:

public static Vector3f scaledAdd( Vector3f target, Vector3f source, float scale ) {

target.x += source.x * scale;

target.y += source.y * scale;

target.z += source.z * scale;

return target;

}



And in my double-based math stuff I have a version of this method on my own Vector3d. :slight_smile:

There are also the Vector constants (Vector3f.UNIT_Y, …) which are actually not constants, and can be modified by accident…

Those would gain to have an immutable Vectors alternative object.

No, it’s just not possible. There is no implementation that would work… especially since vector3f exposes its fields directly. There just isn’t a way to do it without killing the performance of everything for everyone.



We cannot protect users from all of the mistakes they will make. So there must be a balance between performance and safety.

Also note that due to the fact that there is no “stack” in java, the objects that are generated in a stack-like situation are cleaned by the GC very fast and efficiently, basically as performant as the C++ stack.

thank you pspeed

scaledAdd( v, F, dt );

scaledAdd( r, v, dt );

works well, I dindn’t know that x,y,z fields of Vectro3f are visible externally from class. It’s for me much better than make it private.



I’m a bit lost in the other discussion. Nevertheless - it would be also usefull to know when a vector is cloned and when just pointer is copied

for example in

Box1 = new Geometry(“Box”, new Box( A, B);

A.addLocal(1,1,1);

Would this change position of Box1? - This is just example, I’m always not sure anywhere where I pass vectors.

It’s again question about effectivness, I don’t want to bother writing own rutines, if I find that somewher in to process of rendering new objects are still created and that this kills CPU and memory performance.



Or maybe allocation of new objects is not a problem in Java? - as said normen?

You mostly do not pass vectors, you set internal vectors with the data of your current vector (e.g. in setLocalTranslation etc.). So in the example you gave the box location would not change. You do however get an internal vector with getLocalTranslation() but you should treat it as immutable because if you don’t use the setter the location will not be updated properly. To be sure in a certain case, just right-click the method and select “Go to Source” to see the source and what it does. And as said, you do not really need to care for object creation “in stack” more than you would with creating new stack variables in C/C++. And some Java coding conventions: variables/fields and methods are lower case, except maybe static final fields. Classes are upper case, always.

normen > thank’s



OK, just last question, what is recomanded (most efficient) approach if I want vizualize motion of large number (thousands) of simple objects according to user defined equations of motion?



The easies way I see is to make one instance of the objects

[java]class MyBody{

float vx,vy,vz; // velocity

float x,y,z; // possition

float mass;

}

[/java]

to propagate equation of motion, and an other instance (of type com.jme3.scene.Geometry) to visualize it?

however I guess com.jme3.scene.Geometry need large amount of memory, and also it could be a slow-down to move all Geometry instances in each frame by myGeometry.setLocalTranslation(MyBody.x, MyBody.y, MyBody.z);



I’m not sure if geometry class is supposed to be used this way to visualize large number of very simple objects (Box, sphere)

Check the wiki, Controls are meant to continually update/modify spatials. So you extend a Control and attach it to your spatial and the modifying code/extra methods go to the Control class…

Actually I did a test some time ago with jbullet, that uses a object pool normally, I changed that with normal object allocations, performance difference where on modern jvm near to 0%

Why?

Cause the jvm can!!! stackallocate objects when it determines that you dont use them outside of the scope.

So methods like



Vector3f scale(factor,result){}



can allocate internal used objects with nearly no cost at all, as long as you only return the already given variable you give the JIT compiler much freeroom to do such tricks, While still having a complete defensive coded method with no sideeffects.



Bonus JIT:

The jit can do this under certain circumstances as well, when you instanciate a new object and return this, for example

Code:
public void applygravity(){ local pos = getTranslation() pos.add(Vector3f(0,-10,0) setTranslation(pos) }

setTranslation(Vector3f v){
this.localtranslation.set(v)
}

Node getTranslation(){
return new Vector3f(this.localtranslation)
}


can be found out to do the following at runtime
public void applygravity(){
this.localtranslation-=10
}
The JDK7 and JDK6 ers in the later version do this kind of JIt optimisation, and can do this also for more complex cases (like with a if, they will just create two highly optimized version for each case, and select the correct one at the start)
1 Like

For fluid rendering, I suggest the use of a Mesh in point mode, where you manipulate the positionbuffer each frame,

given a large enough amount of waterdrops (or whatever fluid) this is probably the fastest way