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
0
Question by rule62 · Mar 12, 2011 at 03:17 PM · rotationquaternionextrusiontube

Fix ugly extrusions (Quaternions)?

I'm using the extrusion routine in the Unity3D procedural examples. I have a path of points along which I am extruding a "tube" based on a circle profile.

I get these ugly "turnovers" (pictures below) that I reckon are a result of this section of the extrusion code:

if (sections.length < 2) return;

 var worldToLocal = transform.worldToLocalMatrix;
 var finalSections = new Matrix4x4[sections.length];
 var previousRotation : Quaternion;

 for (var i=0;i&lt;sections.length;i++)
 {
     if (autoCalculateOrientation)
     {
         if (i == 0)
         {
             var direction = sections[0].point - sections[1].point;
             var rotation = Quaternion.LookRotation(direction, Vector3.up);

             previousRotation = rotation;
             finalSections[i] = worldToLocal * Matrix4x4.TRS(newPosition, rotation, Vector3.one);    
         }
         else if (i != sections.length - 1)
         {   
             direction = sections[i].point - sections[i+1].point;
             rotation = Quaternion.LookRotation(direction, Vector3.up);


             if (Quaternion.Angle (previousRotation, rotation) &gt; 20)
                 rotation = Quaternion.Slerp(previousRotation, rotation, 0.5);

             previousRotation = rotation;
             finalSections[i] = worldToLocal * Matrix4x4.TRS(sections[i].point, rotation, Vector3.one);
         }
         else finalSections[i] = finalSections[i-1];
     }
     else
     {
         if (i == 0)
         {
             finalSections[i] = Matrix4x4.identity;
         }
         else finalSections[i] = worldToLocal * sections[i].matrix;
     }
 }

alt text

alt text

I'm wondering if there's a way to prevent these turnovers. Possibly reverse the rotation specified by the Quaternion? I've tried changing the parameter of the quaternion - vector.right, vector.up, vector.forward, etc. That doesn't correct anything.

Thanks for any suggestions or corrections!

Comment
Add comment
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

3 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Jesse Anders · Mar 14, 2011 at 10:53 AM

The 'parallel transport frame' should solve your problem. (For details, search online for 'parallel transport frame', or search the forum archives over at gamedev.net, as it's been discussed quite a few times there.)

Comment
Add comment · Show 2 · 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
avatar image rule62 · Mar 14, 2011 at 12:42 PM 0
Share

Ah. That certainly looks like the place to find a solution.

avatar image luciferlchaha · Feb 27, 2012 at 02:46 PM 0
Share

If you have solved the problem.Cound you give me somg advices or a example.Thanks a lot!!!

avatar image
0

Answer by morbidcamel · Dec 24, 2013 at 03:19 AM

Hi All,

I took the liberty of translating the PTF logic from Cinder (Github) as I have a similar problem. Let me know if this helps:

     public static class ParallelTransportFrame
     {     
          // Parallel Transport Frames
          //
          //  These methods compute a set of reference frames, defined by their
          //  transformation matrix, along a curve. It is designed so that the 
          //  array of points and the array of matrices used to fetch these routines 
          //  don't need to be ordered as the curve.
          //  
          //  A typical usage would be :
          //
          //      m[0] = Imath::firstFrame( p[0], p[1], p[2] );
          //      for( int i = 1; i < n - 1; i++ )
          //      {
          //          m[i] = Imath::nextFrame( m[i-1], p[i-1], p[i], t[i-1], t[i] );
          //      }
          //      m[n-1] = Imath::lastFrame( m[n-2], p[n-2], p[n-1] );
          //
          //  See Graphics Gems I for the underlying algorithm.
          //  These are also called Parallel Transport Frames
          //    see Game Programming Gems 2, Section 2.5
 
         public static Matrix4x4 FirstFrame( 
                Vector3 firstPoint, 
                Vector3 secondPoint,
                Vector3 thirdPoint )
         {
             Vector3 t = ( secondPoint - firstPoint ).normalized;
             
             
             Vector3 n = Vector3.Cross(t, thirdPoint - firstPoint ).normalized;
             if( n == Vector3.zero ) 
             {
                 int i = Mathf.Abs( t[0] ) < Mathf.Abs( t[1] ) ? 0 : 1;
                 if( Mathf.Abs( t[2] ) < Mathf.Abs( t[i] ) ) i = 2;
                 
                 Vector3 v = Vector3.zero; 
                 v[i] = 1.0f;
                 n = Vector3.Cross( t, v ).normalized;
             }
             
             Vector3 b = Vector3.Cross(t,  n);
             
             Matrix4x4 M = Matrix4x4.zero;
                 M[0] =  b[0]; M[1] =  b[1]; M[2]  =  b[2]; M[3]  = 0.0f;
                 M[4] =  n[0]; M[5] =  n[1]; M[6]  =  n[2]; M[7]  = 0.0f;
                 M[8] =  t[0]; M[9] =  t[1]; M[10] =  t[2]; M[11] = 0.0f;
                 M[12] = firstPoint[0]; M[13] = firstPoint[1]; M[14] = firstPoint[2]; M[15] = 1.0f;
             return M;
         }
 
         public static Matrix4x4 CreateRotation(this Vector3 axis, float angle)
         {
 
             Vector3 unit = axis.normalized;
             float sine   = Mathf.Sin( angle );
             float cosine = Mathf.Cos( angle );
             
             Matrix4x4 ret =  Matrix4x4.zero;
             
             ret[ 0] = unit.x * unit.x * (1 - cosine) + cosine;
             ret[ 1] = unit.x * unit.y * (1 - cosine) + unit.z * sine;
             ret[ 2] = unit.x * unit.z * (1 - cosine) - unit.y * sine;
             ret[ 3] = 0;
             
             ret[ 4] = unit.x * unit.y * (1 - cosine) - unit.z * sine;
             ret[ 5] = unit.y * unit.y * (1 - cosine) + cosine;
             ret[ 6] = unit.y * unit.z * (1 - cosine) + unit.x * sine;
             ret[ 7] = 0;
             
             ret[ 8] = unit.x * unit.z * (1 - cosine) + unit.y * sine;
             ret[ 9] = unit.y * unit.z * (1 - cosine) - unit.x * sine;
             ret[10] = unit.z * unit.z * (1 - cosine) + cosine;
             ret[11] = 0;
             
             ret[12] = 0;
             ret[13] = 0;
             ret[14] = 0;
             ret[15] = 1;
             
             return ret;
         }
 
         public static Matrix4x4 CreateTranslation( this Vector3 v, float w = 1f )
         {
             Matrix4x4 ret = Matrix4x4.zero;
             ret[12] = v.x;
             ret[13] = v.y;
             ret[14] = v.z;
             ret[15] = w;
             
             return ret;
         }
 
         public static Matrix4x4 NextFrame( 
           this Matrix4x4 prevMatrix, 
           Vector3 prevPoint, 
           Vector3 curPoint,
           Vector3 prevTangent, 
           Vector3 curTangent)
         {
             Vector3 a = Vector3.zero;    // Rotation axis.
             float r = 0;                // Rotation angle.
             
             if( ( prevTangent != Vector3.zero ) && ( curTangent != Vector3.zero ) ) 
             {
                 prevTangent.Normalize();
                 curTangent.Normalize();
                 float dot = Vector3.Dot ( prevTangent, curTangent ); 
                 
                 if( dot > 1.0f ) dot = 1.0f; 
                 else if( dot < -1.0f ) dot = -1.0f;
                 
                 r = Mathf.Acos(dot);
                 a = Vector3.Cross( prevTangent, curTangent );
             }
             
             if ( ( a != Vector3.zero ) && ( r != 0.0f ) ) 
             {
 
                 Matrix4x4 R  = CreateRotation(a, r); //Matrix44<T>::createRotation( a, r );        
                 Matrix4x4 Tj = CreateTranslation( curPoint );
                 Matrix4x4 Ti = CreateTranslation( -prevPoint );
                 
                 // Original order of operation:
                 //return prevMatrix * Ti * R * Tj;
                 //
                 // Cinder's order of operation
                 return Tj*R*Ti*prevMatrix;
             }
             else {
                 Matrix4x4 Tr = CreateTranslation( curPoint - prevPoint );
                 // Original order of operation:
                 //return prevMatrix*Tr;
                 //
                 // Cinder's order of operation
                 return Tr*prevMatrix;
             }
         }
 
         public static Matrix4x4 LastFrame(
             Matrix4x4 prevMatrix, 
             Vector3 prevPoint, 
             Vector3 lastPoint )
         {
             // Original order of operation:
             //return prevMatrix * Matrix44<T>::createTranslation( lastPoint - prevPoint );
             //
             // Cinder's order of operation
             return CreateTranslation( lastPoint - prevPoint )*prevMatrix;
         }
     }
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
avatar image
0

Answer by drudiverse · Jul 25, 2014 at 10:47 AM

instead of matrix, i simply rotated the extruded plane using quaternion lookat relative the the previous version of itself. this prevents any next version of the extruded object from being too much rotated compared to the previous... i found the complete post here:

http://answers.unity3d.com/questions/662944/lookrotation-flipping-180-degrees-through-y-axis.html

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Directional booster 1 Answer

Mimic other object's rotation on one axis (with offset) 0 Answers

90 Degree stopping rotation on y-axis issue 0 Answers

Quaternions incorrect? 2 Answers

Clamping a character's head rotation. 1 Answer


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