Problem with inherited scaling on SharedMesh's

Hello,

Im trying to make a little tetris game, so I experiented with added boxes to a node. However somethings strange happens when I add a new mesh. The box and node setup:



// The Nodes translation/scaling
      temp = new BlockBoard("BoardNode");
      temp.setLocalTranslation(new Vector3f(-17, -0.2f, -2));
      temp.setLocalScale(1.5f);
      ....
// The box to be copied
      bimmer = new Box("BimmerBlock", new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
      bimmer.setModelBound(new BoundingBox());
      bimmer.updateModelBound();
// Shared Mesh to be added
      SharedMesh bimmer1Clone = new SharedMesh("bimming"+x+","+y, bimmer);
      bimmer1Clone.setLocalTranslation(new Vector3f(0,1,0));
                .....
                temp.attachChild(bimmer1Clone);



Everytime I add a bimmer1Clone to the temp node it gets larger - The bimmer localScale is increased and the boxes added just gets bigger and bigger unless I do a localScale(1f) on them before adding. Now the most weird thing is, that if I dont do a bimmer1Clone.setLocalTranslation the boxes will not increase in size but rather be moved a bit each time (each time increased moved).

If I don't use a SharedMesh and add a complete new box it works fine. Is this working as intended, if so I would like an explanation because I don't get it  :-o

Thanks for the reply.  The fix works, no longer a problem.



It makes sense the thing that it uses the old values, however, if I dont look at the node while adding a new clone, it uses the masterMesh' original values and applies those. Then if I look at it again and add a new clone it seems to use the values of the clone added just before that:



   protected void simpleInitGame() {
      holder = new Node("Holding MasterMesh");
      masterMesh = new Box("masterMesh", new Vector3f(), new Vector3f(1, 1, 1));
      masterMesh.setModelBound(new BoundingBox());
      masterMesh.updateModelBound();
      
      SharedMesh clone = new SharedMesh("clone1", masterMesh);
      holder.attachChild(clone);      
      holder.setLocalTranslation(new Vector3f(1,4,-3));
      holder.setLocalScale(1.5f);
      rootNode.attachChild(holder);
      KeyBindingManager.getKeyBindingManager().set("addClone", KeyInput.KEY_F);
      KeyBindingManager.getKeyBindingManager().set("print", KeyInput.KEY_R);
   }
   
   protected void simpleUpdate() {
      if (KeyBindingManager.getKeyBindingManager().
               isValidCommand("addClone",false)){
         addClone();
      }
      if (KeyBindingManager.getKeyBindingManager().
               isValidCommand("print",false)){
         System.out.println("Master - Scale: " + masterMesh.getLocalScale());
         System.out.println("Master - Translation: " + masterMesh.getLocalTranslation());
      }      
   }
   
   private void addClone() {
         SharedMesh cloning = new SharedMesh("clone"+Math.random(), masterMesh);
         holder.attachChild(cloning);      
   }



Now the sense stops for me :) Am I doing something wrong, like not updating geometri or?

That's because when the previous node is drawn, it's actually drawing the master mesh. To make sure it's drawn correctly, the coordinates and such of the master are set to that of the clone. So when you create the next clone, it's still set to the coordinates of the last clone drawn. Thus the new clone gets those.



The reason is that I reckon SharedMesh has mostly been used for creating object during init (when nothing is drawn yet). Your use case is far from unreasonable though and hopefully we can find a cheap fix so you won't need the workaround anymore.

why don't you just set the localtranslation/localscale/localrotation for the sharedmesh when you create it? That seems reasonable to me.

I think this is because during rendering of a copy, the original coordinates of the "master" mesh are replaced with that of the clone it is rendering. Then if you create a new clone it will take those coordinates. I'm not saying that's the best way for this to work though :slight_smile:



As a workaround: store the translation/scale/rotation of your master mesh, and restore them before making a new clone. Example for translation:



// declare somewhere in your class
Box mastermesh;
Vector3f masterTranslation;

// our master mesh
public void initMasterMesh() {
 mastermesh = new Box("BimmerBlock", new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
 // your code here..
 masterTranslation = mastermesh.getLocalTranslation();
}

public SharedMesh makeClone() {
 // reset old values
 mastermesh.setLocalTranslation(masterTranslation);
 return new SharedMesh("Clone", masterMesh);
}



And of course don't add the master mesh to the scene.