Static-Scaled Geometries

Does anyone know a simple way to keep 3d objects the same scale regardless of if their parent node is rescaled (ie keep the same world scale for those children objects)? I am having some trouble wrapping my head around this one because I do not want to change the parent object's setScale method. I would like to be able to set an object to be rescalable or not. If it is, if the parent node changes in scale, then the child also changes, otherwise the child stays the same worldscale.

the parents scale is always taken into account when setting the childs scale.

i guess there would be a new spatial flag needed inherit/ noinherit scale, to easily achieve what you want.



    private inheritScale == true   // new
    protected void updateWorldScale() {
        if (parent != null && inheritScale == true) {
            worldScale.set(parent.getWorldScale()).multLocal(localScale);
        } else {
            worldScale.set(localScale);
        }
    }

where is that updateWorldScale method?

it gets called from Node.updateGeometricScale(), this is usually called once per frame on the root node and updates the location, translation scale etc all children.



These are all Methods from the spatial class.



updateGeometricState()

  |

    --> updateWorldData()

              |

                --> updateWorldVectors()

                            |

                            --> updateWorldScale()



my test case:  :slight_smile:


import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.math.Vector3f;
import com.jme.scene.shape.Box;

public class KeepScale extends SimpleGame {

    public KeepScale() {
    }

    @Override
    protected void simpleInitGame() {
        // the left box inherits the parent nodes scale
        MyBox b = new MyBox ("b", new Vector3f(), 1, 1, 1);
        b.setModelBound(new BoundingBox());
        b.updateModelBound();
        b.setLocalTranslation(-115, 0, 0);
        b.setLocalScale(5);
        rootNode.attachChild(b);

        // the right box keeps its own scale
        MyBox c = new MyBox ("c", new Vector3f(), 1, 1, 1);
        c.setModelBound(new BoundingBox());
        c.updateModelBound();
        c.setLocalTranslation(115, 0, 0);
        c.inheritScale = false;
        c.setLocalScale(5);
        rootNode.attachChild(c);

        // scale the root node down
        rootNode.setLocalScale(0.1f);
       
        rootNode.updateGeometricState(1, true);
       
        System.out.println("scale of box B: " +b.getWorldScale());
        System.out.println("scale of box C: " +c.getWorldScale());
    }

    public static void main(String[] args) {
        new KeepScale().start();

    }

    class MyBox extends Box {
        public MyBox(String name, Vector3f center, float xExtent, float yExtent, float zExtent) {
            super(name, center, xExtent, yExtent, zExtent);
        }
        public boolean inheritScale = true;
        protected void updateWorldScale() {
            if ( parent != null && inheritScale == true) {
                worldScale.set(parent.getWorldScale()).multLocal(localScale);
            } else {
                worldScale.set(localScale);
            }
        }
    }
}




But this kind of violates the concept of jme's scenegraph i think.

Can't you put these objects into its own node which is not getting scaled?

Ah I see, yes, that should work. Thanks!