child transformation before and after addParent

Started by kkl, June 13, 2013, 10:40:31 AM

Previous topic - Next topic

kkl

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.

EgonOlsen

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.

kkl

I tried this:


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. 

EgonOlsen

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:


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);
  }

}


kkl

Yea, my object has rotation pivot. Anyway,  I finally made it work by editing your code!


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.