Author Topic: child transformation before and after addParent  (Read 2249 times)

Offline kkl

  • float
  • ****
  • Posts: 291
    • View Profile
child transformation before and after addParent
« on: June 13, 2013, 10:40:31 am »
Hi Egon,

How do we keep the current object world transformation after calling addParent()?

Say,
1. A butterfly flies toward a leaf
2. Butterfly stops at leaf
3. Butterfly addParent(leaf)
4. The butterfly follows the leaf tranformation right at where it stops.

I'd checked this http://www.jpct.net/forum2/index.php/topic,2011.0.html, but the post mentions about removing parent only.
 
« Last Edit: June 13, 2013, 10:43:35 am by kkl »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: child transformation before and after addParent
« Reply #1 on: June 13, 2013, 04:00:09 pm »
For translations, just correct the butterfly's translation so that it represents the difference in position between the leaf and the bufferfly. For rotations...i'm not sure. You might want to try to multiply the butterfly's rotation matrix with the inverse one from the leaf.

Offline kkl

  • float
  • ****
  • Posts: 291
    • View Profile
Re: child transformation before and after addParent
« Reply #2 on: June 14, 2013, 04:17:36 am »
I tried this:

Code: [Select]
SimpleVector vc = butterfly.getTranslation();
SimpleVector vp = leaf.getTranslation();
SimpleVector vr = new SimpleVector();
vr.x = (vc.x - vp.x);
vr.y = (vc.y - vp.y);
vr.z = (vc.z - vp.z);
butterfly.clearTranslation();
butterfly.translate(vr);
Matrix rm = butterfly.getRotationMatrix();
rm.matMul(leaf.getRotationMatrix().invert3x3());
butterfly.setRotationMatrix(rm);
leaf.addChild(butterfly);

but no luck. The location after adding parent is incorrect. 

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: child transformation before and after addParent
« Reply #3 on: June 14, 2013, 04:04:57 pm »
Here's something that seems to work as long as the rotation pivots are at the origin in object space. If they are not, you somehow have to compensate for that, but i didn't have the time to figure it out. Anyway, maybe it helps:

Code: [Select]
import java.awt.Color;

import org.lwjgl.opengl.Display;

import com.threed.jpct.*;
import com.threed.jpct.util.Light;


public class ChildTest
{

  /**
   * @param args
   */
  public static void main(String[] args)
    throws Exception
  {
    FrameBuffer buffer = new FrameBuffer(640, 480, FrameBuffer.SAMPLINGMODE_HARDWARE_ONLY);
    buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
    buffer.enableRenderer(IRenderer.RENDERER_OPENGL);

    World world = new World();
    Light light = new Light(world);
    light.setPosition(new SimpleVector(0, -100, -100));
    light.setAttenuation(-1);
    light.setIntensity(255, 100, 199);

    Object3D obj = Primitives.getEllipsoid(10, 2);
    obj.compile();
    world.addObject(obj);
    obj.rotateZ(1.2f);
    obj.rotateX(-0.62f);
    obj.rotateY(-0.1f);
    obj.translate(20, -10, 10);

    Object3D cone = Primitives.getCone(5);
    cone.compile();
    world.addObject(cone);
    cone.rotateZ(-0.2f);
    cone.rotateY(-0.2f);
    cone.rotateX(0.25f);

    world.buildAllObjects();
    cone.setRotationPivot(SimpleVector.ORIGIN);

    world.getCamera().moveCamera(Camera.CAMERA_MOVEOUT, 100);
    world.getCamera().moveCamera(Camera.CAMERA_MOVEUP, 100);
    world.getCamera().lookAt(obj.getTransformedCenter());
    long start = System.currentTimeMillis();

    while (!Display.isCloseRequested())
    {
      if (start != 0 && System.currentTimeMillis() - start > 1000)
      {
        start = 0;

        Matrix m = obj.getRotationMatrix();
        m = m.invert();
        cone.getRotationMatrix().matMul(m);

        SimpleVector offset = cone.getTranslation().calcSub(obj.getTranslation());
        offset.matMul(m);

        cone.clearTranslation();
        cone.translate(offset);

        obj.addChild(cone);
      }

      if (start == 0)
      {
        obj.translate(-0.25f, 0.25f, -0.25f);
      }
      else
      {
        cone.translate(0.5f, 0, 0);
      }

      buffer.clear(Color.BLUE);

      world.renderScene(buffer);
      world.draw(buffer);

      buffer.update();
      buffer.displayGLOnly();
      Thread.sleep(10);
    }

    System.exit(0);
  }

}


Offline kkl

  • float
  • ****
  • Posts: 291
    • View Profile
Re: child transformation before and after addParent
« Reply #4 on: June 17, 2013, 06:02:33 am »
Yea, my object has rotation pivot. Anyway,  I finally made it work by editing your code!

Code: [Select]
Matrix m = new Matrix(leaf.getRotationMatrix());
m = m.invert();

SimpleVector t = leaf.getRotationPivot();
Matrix bm = butterfly.getRotationMatrix();
bm.translate(-t.x, -t.y, -t.z);
bm.matMul(m);
bm.translate(t);

SimpleVector offset = butterfly.getTranslation().calcSub(leaf.getTranslation());
offset.matMul(m);

butterfly.clearTranslation();
butterfly.translate(offset);

leaf.addChild(butterfly);


Those who need the same transformation may refer to this code.

BTW Egon, thanx for the code. It was really helpful.
« Last Edit: June 17, 2013, 06:11:19 am by kkl »