关于three.js:围绕给定的轴和角度的旋转点正确旋转对象

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

在Three.js中,似乎有很多旋转方式,我个人认为这不是很直观。参见例如这个例子
http://cloud.engineering-bear.com/apps/robot/robot.html Robot Picture

将旋转应用于多个对象时,会得到非常奇怪的意外效果。例如。当我旋转已添加到彼此的对象并开始旋转父对象时,各个对象之间的相对位置会突然变大,而它们原来的位置会不同。我现在正在尝试分组,并希望避免相同的效果。

有关当前状态,请参见http://pi-q-robot.bitplan.com/example/robot?robot=/models/thing3088064.json;有关以下信息,请参见https://github.com/BITPlan/PI-Q-Robot:源代码。

因此,我根据不同的API选项搜索了适当的示例:

回转

1
2
3
4
function renderScene() {
    stats.update();
    //side1.rotation.z += 0.02;
    pivot.rotation.z += 0.02;
  • https://jsfiddle.net/of1vfhzz/1/ rotating cubes
  • https://github.com/mrdoob/three.js/issues/1958

rotationOnAxis

  • three.js在其中心绕Y轴旋转Object3d
  • 如何在Three.js轴上旋转3D对象?
  • ThreeJS-围绕对象自己的轴旋转

rotationAroundWorldAxis

1
   object.rotateAroundWorldAxis(p, ax, r * Math.PI * 2 / frames);
  • 如何在轴世界Three.js上旋转对象?
  • https://stackoverflow.com/a/32038265/1497139
  • https://jsfiddle.net/b4wqxkjn/7/
  • THREE.js在rotateOnWorldAxis之后更新对象的旋转属性

rotationOnWorldAxis

1
object.rotateOnWorldAxis( axis, angle );
  • 绕世界轴旋转

rotationAboutPoint

  • 三个JS枢轴点
  • Three.js中的旋转锚点

setRotationFromAxisAngle

  • https://threejs.org/docs/#api/zh/core/Object3D.setRotationFromAxisAngle

setEulerFromQuaternion

1
2
   quaternion = new THREE.Quaternion().setFromAxisAngle( axisOfRotation, angleOfRotation );
   object.rotation.setEulerFromQuaternion( quaternion );
  • Three.js-围绕某个轴旋转球体

applyMatrix

1
2
this.mesh.updateMatrixWorld(); // important !
childPart.mesh.applyMatrix(new THREE.Matrix4().getInverse(this.mesh.matrixWorld))
  • 我不期望在Three.js中应用矩阵

我喜欢https://stackoverflow.com/a/56427636/1497139的jsFiddle

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

我还发现了以下讨论
discourcee.three.js.org中的枢轴问题

  • https://discourse.threejs.org/t/rotate-group-around-pivot/3656
  • https://discourse.threejs.org/t/how-to-rotate-an-object-around-a-pivot-point/6838 Robot parts
  • https://discourse.threejs.org/t/set-dynamically-generation-groups-pivot-position-to-the-center-of-its-children-objects-position/6349
  • https://discourse.threejs.org/t/my-3d-model-is-not-not-rotating-around-its-origin/3339/3

    • https://jsfiddle.net/blackstrings/c0o3Lm45/
  • https://discourse.threejs.org/t/rotate-object-at-end-point/2190 Rotate around beam

    • https://jsfiddle.net/f2Lommf5/3594/

问题
以上信息都不十分清楚,无法解决要解决的问题。与建议说明解决方案相比,上图更清楚地说明了问题。

a)Cube rotating around cylinder
我想即使将圆柱体移动也要使用圆柱体作为轴。我希望最简单的方法是使用rotateAroundWorldAxis-是在Three.js的最新版本中提供的还是我必须添加它来自https://stackoverflow.com/a/32038265/1497139?

b)我想获得一连串对象以进行旋转,以便稍后像下面那样应用逆运动学

  • https://github.com/jsantell/THREE.IK
  • https://jsantell.github.io/THREE.IK/

尽管我查看了这些解决方案的源代码,但我无法真正找到发生父子定位和旋转的地方。有哪些相关的代码/ API函数行可以使关节围绕关节链正确旋转?
我已经看过Three.js的Bone / Skeleton API,但是那里也有同样的问题-许多行代码,但是在子代和父代之间发生旋转/定位的位置并不清楚。


问题a)

基本上可以按预期工作:

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

看到
https://jsfiddle.net/wf_bitplan_com/4f6ebs90/13/

enter image description here
enter image description here

问题b)

看到
https://codepen.io/seppl2019/pen/zgJVKM

individually rotating arms

关键是正确设置位置。 在这种情况下,将计算大小,而不是https://stackoverflow.com/a/43837053/1497139上的建议。

1
2
3
4
5
6
7
8
9
10
11
// 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);