three.jsrotationinverse-kinematics

Rotating an Object properly around a pivot point given axis and angle


In Three.js there seems to be quite a few ways of rotation which i personally do not find very intuitive. See e.g. the example
http://cloud.engineering-bear.com/apps/robot/robot.html Robot Picture

I get very strange unexpected effects when I apply rotation to multiple objects. E.g. when I rotate objects that have been added to each other and start rotating the parent the individual objects will all over sudden by placed differently in respect to each other then they originally where. I am now experimenting with grouping and would like to avoid the same effect.

See http://pi-q-robot.bitplan.com/example/robot?robot=/models/thing3088064.json for the current state of affairs and https://github.com/BITPlan/PI-Q-Robot for the source code.

So i searched for proper examples following the different API options:

rotation

function renderScene() {
    stats.update();
    //side1.rotation.z += 0.02;
    pivot.rotation.z += 0.02;

rotateOnAxis

rotateAroundWorldAxis

   object.rotateAroundWorldAxis(p, ax, r * Math.PI * 2 / frames);

rotateOnWorldAxis

object.rotateOnWorldAxis( axis, angle );

rotateAboutPoint

setRotationFromAxisAngle

setEulerFromQuaternion

   quaternion = new THREE.Quaternion().setFromAxisAngle( axisOfRotation, angleOfRotation );
   object.rotation.setEulerFromQuaternion( quaternion );

applyMatrix

this.mesh.updateMatrixWorld(); // important !
childPart.mesh.applyMatrix(new THREE.Matrix4().getInverse(this.mesh.matrixWorld))

I like the jsFiddle for https://stackoverflow.com/a/56427636/1497139

  var pivot = new THREE.Object3D();
  pivot.add( cube );
  scene.add( pivot );

I also found the following discussions pivot issue in discourcee.three.js.org

Questions None of the above information is clear enough to get to the point of the problem to be solved. The graphics above are much clearer stating the problem than the proposals are stating a solution.

a)Cube rotating around cylinder I'd like to use the cylinder as the axis even when the cylinder is moved.I'd expect the easiest way to go would be to use rotateAroundWorldAxis - is that available in the latest revision from three.js or do i have to add it from e.g. https://stackoverflow.com/a/32038265/1497139?

b) I'd like to get a chain of objects to be rotated to later apply inverse kinematics as in

Although i looked at the source code of that solutions I can't really find the place where the parent-child positioning and rotating is happening. What are the relevant lines of code / API functions that would make proper rotation around a chain of joints happen? I already looked in the Bone/Skeleton API of Three.js but had the same problem there - lots of lines of code but no clear point where the rotation/positioning between child and parent happens.


Solution

  • Question a)

    Basically it works as expected:

        cylinder.position.set( options.x, 15, options.z );
        pivot.position.x=options.x;
        pivot.position.z=options.z;
    

    see https://jsfiddle.net/wf_bitplan_com/4f6ebs90/13/

    enter image description here enter image description here

    Question b)

    see https://codepen.io/seppl2019/pen/zgJVKM

    individually rotating arms

    The key is to set the positions correctly. Instead of the proposal at https://stackoverflow.com/a/43837053/1497139 the size is computed in this case.

    // create the pivot to rotate around/about
    this.pivot = new THREE.Group();
    this.pivot.add(this.mesh);
    // shift the pivot position to fit my size + the size of the joint
    this.pivot.position.set(
          x,
          y + this.size.y / 2 + this.pivotr,
          z + this.size.z / 2
    );
    // reposition the mesh accordingly
    this.mesh.position.set(0, this.size.y / 2, 0);