The right way to rotate a object

Hi, this is the question. I try do it in this two ways:


  1. with the rotate method of spatial



    [java]

    obj.rotate(0.0f, 0.0f, Math.toRadian(45.0f));

    [/java]



    this method return a new object (Spatial) and this affect the performance and the lost memory.


  2. with the setLocalRotate of spatial



    this code rotate the spatial’s Z axis 45 degrees in 1 second.

    [java]

    // fields of the class

    private float angle = 0.0f;

    private float angleToRotate = 0.0f;

    private float acumTpf = 0.0f;

    private Quaternion rotQuaternion;

    private Vector3f rotVector;



    // In the constructor

    angle = Math.toRadians(45.0f);

    rotQuaternion = new Quaternion();

    rotVector = new Vector3f(0,0,1.0f);



    // in simpleUpdate



    if (left || right) {



    acumTpf += tpf;

    if (acumTpf > 1)

    acumTpf = 1.0f



    } else {

    if (acumTpf > 0) {



    acumTpf -= tpf;

    if (acumTpf < 0)

    acumTpf = 0.0f;



    }

    }



    if (left)

    angleToRotate = angle;

    else if (right)

    angleToRotate = -angle;



    rotQuaternion.fromAngleAxis( angle * acumTpf , rotVector );

    geom.setLocalRotation(rotQuaternion);

    [/java]



    the method fromAngleAxis return a new Quaternion object, another new object.



    which is the correct way to rotate an spatial without create a new object? I need to do, is to rotate an object on the left or right as press the arrows, and if you do not press any return the object to its original rotation gradually.



    The Optimization topic of the documentation says





    Avoid creating new objects



    When you use math operations like vectorA.mult(vectorB);, they create new objects for the result. These objects have to be garbage collected when you don’t use them anymore.



    Check your math operations for opportunities to use the local version of the math operations, e.g. vectorA.multLocal(vectorB). Local methods store the result in vectorA and do not create a new object. Use local methods if you do not need to keep the previous vectorA.







    Thanks.

Depends on how you want it rotated.

Sorry, had posted the incomplete question, this is the full question.



Thanks.

I think you are too worried about object creation in this case. Avoiding it will be very hard in this case and probably not give you any real gain.



Optimizing too early is one if the biggest mistakes.

3 Likes

Yes, I only think that create a new object only for rotate a spatial is wrong. Why no fond a "void setLocalRotation(float x, float y, float z)?

I’m just discarding possibilities, since my game when start shooting or rotate the ship, the game slows down, until I stop and spend a few instances to normal speed, I think this is because the garbage collector runs and frees up resources, then I am trying to remove all objects inecesarias creations.



Thanks.

@proteo1903 said:
Yes, I only think that create a new object only for rotate a spatial is wrong. Why no fond a "void setLocalRotation(float x, float y, float z)?
I'm just discarding possibilities, since my game when start shooting or rotate the ship, the game slows down, until I stop and spend a few instances to normal speed, I think this is because the garbage collector runs and frees up resources, then I am trying to remove all objects inecesarias creations.

Thanks.

This is definitely *not* because you create vectors, you'd have to create hundreds of thousands of them per update loop to see any kind of slowdown really.
1 Like

Ok, I will review my code and looking for any spatial that continue update its custom control when it is not in the screen.



Thanks for all.

@proteo1903 said:
Ok, I will review my code and looking for any spatial that continue update its custom control when it is not in the screen.

Thanks for all.

They always do. If you want your control to stop updating when the spatial is culled, check its cull state in the update() method.
@proteo1903 said:
Yes, I only think that create a new object only for rotate a spatial is wrong. Why no fond a "void setLocalRotation(float x, float y, float z)?
I'm just discarding possibilities, since my game when start shooting or rotate the ship, the game slows down, until I stop and spend a few instances to normal speed, I think this is because the garbage collector runs and frees up resources, then I am trying to remove all objects inecesarias creations.

Thanks.


Is this on Android or regular desktop Java? If this is on regular desktop Java then your problem is absolutely 100% something else. Garbage collecting temporary objects on modern desktop Java is pretty much free. This will be such a teeny tiny part of everything else that is going on that you would have to have thousands and thousands of constantly moving/rotating objects before you'd notice any millisecond level slow down from creating new Quaternions every frame. The other processing done when an object is rotated dwarfs this in comparison.

I, test the game in desktop, but my intention is run this in android devices.

@pspeed said:

Is this on Android or regular desktop Java? If this is on regular desktop Java then your problem is absolutely 100% something else. Garbage collecting temporary objects on modern desktop Java is pretty much free. This will be such a teeny tiny part of everything else that is going on that you would have to have thousands and thousands of constantly moving/rotating objects before you’d notice any millisecond level slow down from creating new Quaternions every frame. The other processing done when an object is rotated dwarfs this in comparison.



I'm test the game in desktop, but my intention is run this in android devices. Because this, I try to not give work to the garbage collector. I does developed an 2d game framework for android and in it try to not create object if isn't necesary and use pool of objecto to recicle object when I need a new object. Because this I have the idea of not create objects if is no necesary.

Thanks.

Essentially if doing a chain of operations like add then multiply then whatever - you should always use the local variant as a matter of course.



… however if you start doing complex things then you are falling into the trap of premature optimization.



… which is really easy to do



… and can lead to really painful results.

@normen said:
They always do. If you want your control to stop updating when the spatial is culled, check its cull state in the update() method.


I thought that if I called the method removeFromParent (), controls the the spatials not updating, is this correct?

thanks.
@proteo1903 said:
I thought that if I called the method removeFromParent (), controls the the spatials not updating, is this correct?

thanks.

Ah, yeah sure, I thought you were talking about the automatic culling outside the cameras view.

removeFromParent() will also cause GC.

If you are seeing performance problems then you should probably track them down. I can super-guarantee you that you are looking in the wrong place, right now.



And if you are not seeing performance problems… well, then you probably really enjoy puzzles. So enjoy. :slight_smile:

@normen said:
Ah, yeah sure, I thought you were talking about the automatic culling outside the cameras view.


I do the follow, for example, when a bullet collided with an actor, it is remove from parent and put in the Bullet's pool to be utilized. It is right?
@proteo1903 said:
I do the follow, for example, when a bullet collided with an actor, it is remove from parent and put in the Bullet's pool to be utilized. It is right?

Sorry I don't understand. Its normal java objects and they behave like that as well.
@pspeed said:
If you are seeing performance problems then you should probably track them down. I can super-guarantee you that you are looking in the wrong place, right now.

And if you are not seeing performance problems... well, then you probably really enjoy puzzles. So enjoy. :)


Jajajajaa, Maybe you are right, I will review my code to find the problem, Thanks you for all.
@normen said:
Sorry I don't understand. Its normal java objects and they behave like that as well.


I use a pool of object for recicle object, I take this technique from the book of Mario Zechner, Beggining Android Games, in it you request for a instance of an object and release then when you don't need anymore, this prevent to give more work to the GC.
In my case, the bullets come from the pool, and when collide with any object, I remove the spatial from it parent (rootNode) and release it to the pool again ready to use when I need it.
@pspeed said:
removeFromParent() will also cause GC.


But the reference to the spatial not be lost

[java]
Spatial obj =assetmanager.loadModel(.....
rootNode.attachChild(obj);
obj.removeFromParent();
[/java]

obj mantain a reference to the spatial, the GC should no free this.