How to attachChild but leave child in same world coords?

This is quite possibly a stupid question and it seems like it must have been asked before, but really, I did search the archives and the wiki.  :slight_smile:

Is there a quick way to use attachChild but leave the spatial in the same worldspace postion&rotation&scaling&shearing in jME? Usually I would do this by multing parentMatrix inverse and the world matrix, (or was it the other way around?). However Spatial and Node don't give me these matrices. Is there a jME short cut for either building the full parent & old world matrix or some other way of setting the child back to it's old worldPosition?



Matrix4f.set(Quaternion) & Matrix4f.setTranslation(Vector3f) but that ignores scaling and shearing, right? Or is scaling not valid here somehow?

In jmephysics these two method are used for that:


   /**
    * Sets the world translation of a spatial according to a supplied body.
    * This is done by going "the other way around"; figuring
    * out what its local translation has to be in order for the world
    * translation to be the same as the one of the body.
    *
    * @param spat The Spatial to synchronize.
    * @param body The body to synchronize the Spatial to.
    */
   private void setWorldTranslation(Spatial spat, Body body) {
      Vector3f tmpPos = spat.getLocalTranslation();
      if (spat.getParent() != null) {
         tmpPos.set(odePos).subtractLocal(spat.getParent().getWorldTranslation());
         tmpPos.divideLocal(spat.getParent().getWorldScale());
         inverseWorldRotation.set(spat.getParent().getWorldRotation()).inverseLocal()
               .multLocal(tmpPos);
      } else {
         tmpPos.set(odePos);
      }
   }
   
   /**
    * Sets the world rotation of a spatial according to a supplied body.
    * This is done by going "the other way around"; figuring
    * out what its local rotation has to be in order for the world
    * rotation to be the same as the one of the body.
    *
    * @param spat The Spatial to synchronize.
    * @param body The body to synchronize the Spatial to.
    */
   private void setWorldRotation(Spatial spat, Body body) {
      Quaternion tmpQuat = spat.getLocalRotation();
      if (spat.getParent() != null) {
         inverseWorldRotation.set(spat.getParent().getWorldRotation()).inverseLocal().mult(
               odeRot, tmpQuat);
      } else {
         tmpQuat.set(odeRot);
      }
   }


(would be similar for scale)

Hope that helps.

yes, it does help,thanks. I can use these as is, but is there any reasone these aren't convenience methods on Spatial?

Strange bit of code that never uses one of it's arguements (body) and doesn't even seem alter what it claims(spat), unless I'm missing something. Anyway, it is pretty helpful, once I get something more general working, i'll post it.

Yeah, 'body' indeed is not used any more but the odePos and odeRot fields in the same class.

Nonetheless, it does change spat! It calls getLocalTranslation() and modifies that vector - which moves the spatial! Respective getLocalRotation.

Ah yes, reference vs value. Thanks for clearing that up. What is inverseWorldRotation acting on?

What is inverseWorldRotation acting on?

inverseWorldRotation.set(spat.getParent().getWorldRotation()).inverseLocal()
.multLocal(tmpPos);


alters tmpPos
and

inverseWorldRotation.set(spat.getParent().getWorldRotation()).inverseLocal().mult(
odeRot, tmpQuat);


reads odeRot multiplies inverseWorldRotation with it and store result in tmpQuat