Quantcast
Channel: Questions in topic: "parenting"
Viewing all articles
Browse latest Browse all 302

Problem combining transform.rotation and hierarchical rotations

$
0
0
Hi, I try to implement a forward kinematics system to transfer absolute joint positions of a skeleton to joint rotations and to rotate the whole skeleton in the scene. I already transferred the positions in global orientations for each joint and I can transfer all hierarchical rotations i need, but I can't rotate the whole body in the scene. To demonstrate my problem I made an example scene where the joint system represent a simple skeleton model: ![alt text][1] Each joint system consists of an empty game object called System and three Joints which are represented by a coordinate systems. The first joint is a child of the System game object and its position is at the top center of the numbers you see in the scene. The second joint is a child of the first and the third is a child of the second joint (see the hierarchy screenshot). ![alt text][2] System 1 (the selected/highlighted one) shows the 3 hierarchical joints pointing in the needed directions with LookRotation. Y/up shall point to the next joint position and z/forward simply points to Vector3.forward. For simplicity these values are set and not calculated in this example. If I apply a rotation to the whole system, in the editor I can see that the empty parent game object is rotated but the joints (the child objects) are not. This is the update code for this system: void Update () { transform.Rotate(Vector3.up, currAngle); transforms[0].localRotation = Quaternion.Inverse(transform.rotation) * Quaternion.LookRotation(Vector3.forward, new Vector3(1.0f, 0.0f, 0.0f)); transforms[1].localRotation = Quaternion.Inverse(transforms[0].rotation) * Quaternion.LookRotation(Vector3.forward, new Vector3(0.0f, -1.0f, 0.0f)); transforms[2].localRotation = Quaternion.Inverse(transforms[1].rotation) * Quaternion.LookRotation(Vector3.forward, new Vector3(0.0f, -.5f, -.5f)); // just some value generation if (currAngle > 1) { raise = false; } else if (currAngle < 0) { raise = true; } currAngle += raise ? step : -step; } The script is attached to the System game object. So transform is the joint system's transform. The array transforms consists of the three joints (transforms[0] is the first joint, transforms[1] the second and so on). In system 2 I don't multiply the inverse of the parent rotation to the global rotation of the joint. Now the whole system can be rotated but the orientation of the second and third joints are wrong. transform.Rotate(Vector3.up, currAngle); transforms[0].localRotation = Quaternion.LookRotation(Vector3.forward, new Vector3(1.0f, 0.0f, 0.0f)); transforms[1].localRotation = Quaternion.LookRotation(Vector3.forward, new Vector3(0.0f, -1.0f, 0.0f)); transforms[2].localRotation = Quaternion.LookRotation(Vector3.forward, new Vector3(0.0f, -.5f, -.5f)); If i apply the inverse to the second and third joint again (system 3), the orientation of them stays the same for the whole rotation. transform.Rotate(Vector3.up, currAngle); transforms[0].localRotation = Quaternion.LookRotation(Vector3.forward, new Vector3(1.0f, 0.0f, 0.0f)); transforms[1].localRotation = Quaternion.Inverse(transforms[0].rotation) * Quaternion.LookRotation(Vector3.forward, new Vector3(0.0f, -1.0f, 0.0f)); transforms[2].localRotation = Quaternion.Inverse(transforms[1].rotation) * Quaternion.LookRotation(Vector3.forward, new Vector3(0.0f, -.5f, -.5f)); The first system shows the correct joint orientations, but the system as a whole is not rotated. How can I apply the system rotation to all child joint rotations like in system 2 and 3 without overwriting their local orientation? ---------- **Solution:** While describing the problem more clearly, I had the idea to multiply LookRotate with transform.rotation. For a skeleton model, this means that all global joint rotation must be multiplied with the global rotation of the skeleton, before they are multiplied with the inverse rotation of the parent. System 1 now shows the effect I wanted: ![alt text][3] The new code for this system is: transform.Rotate(Vector3.up, _currAngle); Transforms[0].localRotation = Quaternion.Inverse(transform.rotation) * transform.rotation * Quaternion.LookRotation(Vector3.forward, new Vector3(1.0f, 0.0f, 0.0f)); Transforms[1].localRotation = Quaternion.Inverse(Transforms[0].rotation) * transform.rotation * Quaternion.LookRotation(Vector3.forward, new Vector3(0.0f, -1.0f, 0.0f)); Transforms[2].localRotation = Quaternion.Inverse(Transforms[1].rotation) * transform.rotation * Quaternion.LookRotation(Vector3.Cross(new Vector3(0.0f, -.5f, -.5f), Vector3.right), new Vector3(0.0f, -.5f, -.5f)); [1]: https://media.giphy.com/media/kiulScxzkE0tm4E8Mr/giphy.gif [2]: /storage/temp/121856-scene-hierarchy.jpg [3]: https://media.giphy.com/media/9PnTyOROkdbgdUs9kb/giphy.gif

Viewing all articles
Browse latest Browse all 302

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>