Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by bm212 · May 01, 2011 at 10:04 PM · rotationquaternionangleaxis

Strange behaviour with Quaternion.AngleAxis

I have a jointed character and I'm trying to use some IK-type logic for generating procedural walking animations. I'm using a very constrained set up which means I can solve the resulting equations analytically. Each section of the leg is a GameObject with the usual parenting relationships (i.e. hip->knee->ankle). I'm considering each joint in the leg as being able to rotate only through 1 axis, effectively the the x-axis of the body (in my case, body y is up, body z is forward). This means that my character's knees can hinge in the expected manner (i.e. forward and back), and the hips are similarly only allowed to swing forwards and back (no side-to-side movement or rotation is permitted).

I'm doing the rotation of the knee like so:

private Transform knee; ...

float currentAngle = calculateCurrentRotationAngleToWorldVertical(knee); float desiredAngle = calculateDesiredRotationAngleToWorldVertical(knee); float delta = Mathf.DeltaAngle(currentAngle, desiredAngle);

Vector3 rotationAxisInLocalSpace = knee.InverseTransformDirection(rotationAxisInWorldSpace); Quaternion q = Quaternion.AngleAxis(delta, rotationAxisInLocalSpace); knee.localRotation *= q;

i.e. I first measure the angle of the knee relative to vertical (with all vectors projected into the plane of the rotation axis), then calculate the desired angle of the knee relative to vertical, figure the change in angle and apply that rotation about the rotation axis to the knee's local rotation quaternion. I haven't supplied details of how I calculate the current and desired rotation angles as I don't think they are directly relevant, but I can add them if required.

This works most of the time, but occasionally seems to generate rather odd results. Sometimes it seems to rotate the wrong way around the rotation axis. For example, the knee is initially rotated such that the angle between it and the world y axis is 143.9 degrees. The desired angle is 170 degrees, so the delta is +26.1 degrees (i.e. 170 - 143.9 = 26.1). When I do the rotation as above, it goes the wrong way, and if I measure the angle afterwards, I see that it is actually 117.8 degrees, i.e. it has subtracted the delta, not added it.

Does anyone know why this is happening? Is it some subtlety of quaternion maths that I'm ignorant of?

Any help much appreciated.

Edit - the issue seems to surface if the stride length decreases (i.e. if the character is trying to move his foot back towards his body).

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Peter G · May 01, 2011 at 11:54 PM 1
Share

Have you debugged float currentAngle = calculateCurrentRotationAngleToWorldVertical(knee); float desiredAngle = calculateDesiredRotationAngleToWorldVertical(knee); to make sure that they are putting out the right angle every time.

avatar image Bunny83 · May 01, 2011 at 11:55 PM 1
Share

Hmm, the only thing i can think of (if your magic I$$anonymous$$ works ;) ) is that maybe something is wrong with your rotation axis. Could it be that it's pointing into the wrong direction sometimes? $$anonymous$$aybe try to use Debug.DrawLine(). I've never written my own I$$anonymous$$ solver, but some day i will ;). AFAI$$anonymous$$ there's no known bug in Quaternion.AngleAxis.

avatar image bm212 · May 02, 2011 at 11:04 AM 0
Share

I think it's something to do with not being able to distinguish an angle of +x from one of -x when using Vector3.Angle. I'll carry out some experiments and post my results.

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by bm212 · May 02, 2011 at 09:01 PM

I've found a solution, but it's a horrible hack and I think it simply highlights my lack of understanding about the way quaternions work.

If I do a Quaternion.AngleAxis to tell it to rotate -90 degrees about (1,0,0) in world space, and then do Quaternion.ToAngleAxis on the resulting quaternion output, I get an angle of +90 degrees about (-1,0,0). This should be ok, but it seems like it is actually doing a rotation of 90 degrees about (+1,0,0). As a result, I can hack my way around the problem like so:

Quaternion q = Quaternion.AngleAxis(delta, rotationAxisInLocalSpace);
float angle = 0.0f;
Vector3 axis = Vector3.zero;
q.ToAngleAxis(out angle, out axis);
if (!axis.Equals(rotationAxisInWorldSpace)) {
    knee.localRotation*=Quaternion.Inverse(q);
}
else {
    knee.localRotation *=q;
}

Pretty horrible, and requires quite a lot of spurious calculation. If anyone can suggest a better way, I'd love to hear it.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

No one has followed this question yet.

Related Questions

Rotation from AngleAxis() ToAngleAxis() flips back and forth 1 Answer

reproducing hingejoint.angle 0 Answers

Problem rotating object around particular axis 1 Answer

Change the roll of the rotation 0 Answers

object is not rotating from right direction 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges