Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Corner Angle Revisited
#1
Bug 
For a while I have been using this code to measure cornering lean

Code:
                //CORNERING LEAN
                float BikeTFDistance = Spline.TFToDistance(BikeTF, CurvyClamping.Clamp);


                Vector3 Cornerbehind = Spline.GetTangentByDistance(BikeTFDistance - 0.5f,Space.World);
                Vector3 Cornercomingup = Spline.GetTangentByDistance(BikeTFDistance + 0.5f, Space.World);
                
                Cornerbehind.y = 0;
                Cornercomingup.y = 0;
                newcornerangle = Vector3.SignedAngle(Cornerbehind, Cornercomingup, Vector3.up);

                delta = newcornerangle - lastcornerangle;

                delta *= Time.deltaTime;

                lastcornerangle += delta;

it was working really well until recently when I realised it was giving me terrible results on splines that aren't totally flat on the xz plane. 

So much so that I drew the tangent lines with this to debug

 
Code:
                float linelength = 5f;
                Debug.DrawLine(mRigidBody.transform.position, mRigidBody.transform.position + Cornerbehind.normalized * linelength, Color.blue, 0.01f);
                Debug.DrawLine(mRigidBody.transform.position, mRigidBody.transform.position + Cornercomingup.normalized * linelength, Color.red, 0.01f);

Added some pictures below - the tangent lines give a really beautiful almost perpendicular tangent against the spline when the spline is flat as you would expect.

   

 As soon as the spline goes even slightly up or down then the tangents shoot off together wildly to the left or right. What could be causing this?
   
Reply
#2
Either I've misunderstood the way the method works or this might be a bug with GetTangentByDistance but not sure - is there another approach I can check?
Reply
#3
Heya I need to add some colour to this sorry - the info above is misinformed. I just tested the leaning code in a new scene with a huge undulating 5km road and it worked perfectly. There's something wrong with the cached data I think of that one spline in particular.

I will add that something similar like this used to happened occasionally before where I saw that my splines data wasn't somehow refreshed properly so I deleted them all and started again - maybe im missing some option to fresh the cache somehow but I think there's a possibility for an overlap of spline reference data somewhere which explains why those tangents are pointing in a completely different direction - the data is pointing to another spline. It's difficult to repro tbh and the easiest way I found to refresh was to delete the spline/ curvy global manager and create a new one. But not sure if I can safely do this now that I have many more splines in my actual game world.
Reply
#4
Hi Samy,

I would be surprised if the issue is due to outdate cache, but I stay open to this possibility. The problem not being easily reproducible makes it difficult to debug, but let's try something: Before using a spline in your code, force it to refresh by calling spine.Refresh().

In the lack of a reproduction case, what I suspect is a potential lack of precision in the data used to compute the tangent.
You use GetTangentByDistance. This one compares to neighboring point's position to deduce the tangent. Neighboring in this context is 0.01 tf difference. For a very long spline, 0.01 tf can be a significant distance.
If this is the issue, then I seen two solutions (and at the same time ways to confirm or not that this is the issue):
1- Use GetTangentByDistanceFast: this one used the spline's cache. You can control the caches's density in the spline's settings.
2- Modify GetTangentByDistance's code to make the delta a value other than 0.01 tf.

I hope this helped.
Have a great

PS:
Looking at your code, I see something that bothers me:
delta *= Time.deltaTime;
lastcornerangle += delta;
I don't know where lastcornerangle and delta are used later on, so maybe this code is doing what it shoudl be, but the multipication with deltaTime seems weird to me.
Please consider leaving a review for Curvy. This will help a lot keeping Curvy relevant in the eyes of the Asset Store algorithm.
Reply
#5
(12-23-2023, 01:39 PM)_Aka_ Wrote: Hi Samy,

I would be surprised if the issue is due to outdate cache, but I stay open to this possibility. The problem not being easily reproducible makes it difficult to debug, but let's try something: Before using a spline in your code, force it to refresh by calling spine.Refresh().

In the lack of a reproduction case, what I suspect is a potential lack of precision in the data used to compute the tangent.
You use GetTangentByDistance. This one compares to neighboring point's position to deduce the tangent. Neighboring in this context is 0.01 tf difference. For a very long spline, 0.01 tf can be a significant distance.
If this is the issue, then I seen two solutions (and at the same time ways to confirm or not that this is the issue):
1- Use GetTangentByDistanceFast: this one used the spline's cache. You can control the caches's density in the spline's settings.
2- Modify GetTangentByDistance's code to make the delta a value other than 0.01 tf.

I hope this helped.
Have a great

PS:
Looking at your code, I see something that bothers me:
delta *= Time.deltaTime;
lastcornerangle += delta;
I don't know where lastcornerangle and delta are used later on, so maybe this code is doing what it shoudl be, but the multipication with deltaTime seems weird to me.

Totally fair and I'll try to do more investigating and make the suggested changes. You're right that the multiplication by time.deltatime there is a bit unorthodox but it's just another way to apply smoothing to an ongoing changing variable. It's like when you sometimes see currentvalue = mathf.lerp(currentvalue, targetvalue, time.deltatime). Technically not the way it was intended to be implemented but it works as a hack. I'm glad I only showed you this snippet of my code because if you saw the rest you would call the police  Big Grin
Reply
#6
(12-27-2023, 09:59 PM)SAMYTHEBIGJUICY Wrote: [quote="_Aka_" pid='6389' dateline='1703338793']
Hi Samy,

I would be surprised if the issue is due to outdate cache, but I stay open to this possibility. The problem not being easily reproducible makes it difficult to debug, but let's try something: Before using a spline in your code, force it to refresh by calling spine.Refresh().

In the lack of a reproduction case, what I suspect is a potential lack of precision in the data used to compute the tangent.
You use GetTangentByDistance. This one compares to neighboring point's position to deduce the tangent. Neighboring in this context is 0.01 tf difference. For a very long spline, 0.01 tf can be a significant distance.
If this is the issue, then I seen two solutions (and at the same time ways to confirm or not that this is the issue):
1- Use GetTangentByDistanceFast: this one used the spline's cache. You can control the caches's density in the spline's settings.
2- Modify GetTangentByDistance's code to make the delta a value other than 0.01 tf.

I hope this helped.
Have a great

PS:
Looking at your code, I see something that bothers me:
delta *= Time.deltaTime;
lastcornerangle += delta;
I don't know where lastcornerangle and delta are used later on, so maybe this code is doing what it shoudl be, but the multipication with deltaTime seems weird to me.

I found the issue after a lot of testing but happy to finally report on it. The problem arises when you have nested splines and their relative positions in the game world versus the control points underneath them. What I have discovered is that it is important where you place your spline's parent object, I can either position it close to where I expect the control points to be or I can use the automatic placing of 0,0,0.

This is easiest illustrated with an example.
See below I have two splines with almost identical first control point positions in the game world.

Currently, we are on curvy spline 16, positioned close to the player's world position, which gives us tangent differences as expected (the blue and red lines coming out of my player)
   

If I switch to spline 17 - which has a world position of 0,0,0, the tangents show the erroneous result, because the children have very high values for their local coordinates, which means the relative values of the control points have a max tolerance for accurate calculations. Or this is a floating point error issue as the values get larger. 
   
Reply
#7
BTW I implemented a smoothdamp instead so I dont get blocked from this forum Big Grin

float targetAngle = Mathf.Clamp(newcornerangle, -maxlean, maxlean);
lastcornerangle = Mathf.SmoothDamp(lastcornerangle, targetAngle, ref angleVelocity, smoothTime);
Reply
#8
(12-27-2023, 09:59 PM)SAMYTHEBIGJUICY Wrote: I'm glad I only showed you this snippet of my code because if you saw the rest you would call the police  Big Grin
Or maybe even the SWAT Big Grin

(12-28-2023, 10:59 PM)SAMYTHEBIGJUICY Wrote: BTW I implemented a smoothdamp instead so I dont get blocked from this forum Big Grin
That was a close call :p
Please consider leaving a review for Curvy. This will help a lot keeping Curvy relevant in the eyes of the Asset Store algorithm.
Reply
#9
(12-28-2023, 12:10 PM)SAMYTHEBIGJUICY Wrote: The problem arises when you have nested splines and their relative positions in the game world versus the control points underneath them. What I have discovered is that it is important where you place your spline's parent object, I can either position it close to where I expect the control points to be or I can use the automatic placing of 0,0,0.

This is easiest illustrated with an example.
See below I have two splines with almost identical first control point positions in the game world.

Currently, we are on curvy spline 16, positioned close to the player's world position, which gives us tangent differences as expected (the blue and red lines coming out of my player)


If I switch to spline 17 - which has a world position of 0,0,0, the tangents show the erroneous result, because the children have very high values for their local coordinates, which means the relative values of the control points have a max tolerance for accurate calculations. Or this is a floating point error issue as the values get larger. 

Hi

I tried to reproduce this with two splines having exactly the same shape (superposing), the only difference being the coordinates of the spline game object. I saw no difference. I attached the test data for you to try on your side. This makes me think that the coordinate of the spline GO is not issue, at least not in such value ranges.

The screenshots you attached to your post show two splines that are not superposed. I get that this is to make the screenshots easiest to understand, but I am curious in the result of tests where the two splines are exactly superposing.

If you open the attached scene, you will find a GO named TangentTester. You can see that whatever the spline you assign as an input for the test the tangent is the same.

Let me know if you manage to reproduce the issue with superposing splines.

Have a nice weekend, and happy new year.


Attached Files
.cs   temp.cs (Size: 879 bytes / Downloads: 2)
.unity   tmp.unity (Size: 40.98 KB / Downloads: 1)
Please consider leaving a review for Curvy. This will help a lot keeping Curvy relevant in the eyes of the Asset Store algorithm.
Reply
#10
(12-29-2023, 10:26 PM)_Aka_ Wrote:
(12-28-2023, 12:10 PM)SAMYTHEBIGJUICY Wrote: The problem arises when you have nested splines and their relative positions in the game world versus the control points underneath them. What I have discovered is that it is important where you place your spline's parent object, I can either position it close to where I expect the control points to be or I can use the automatic placing of 0,0,0.

This is easiest illustrated with an example.
See below I have two splines with almost identical first control point positions in the game world.

Currently, we are on curvy spline 16, positioned close to the player's world position, which gives us tangent differences as expected (the blue and red lines coming out of my player)


If I switch to spline 17 - which has a world position of 0,0,0, the tangents show the erroneous result, because the children have very high values for their local coordinates, which means the relative values of the control points have a max tolerance for accurate calculations. Or this is a floating point error issue as the values get larger. 

Hi

I tried to reproduce this with two splines having exactly the same shape (superposing), the only difference being the coordinates of the spline game object. I saw no difference. I attached the test data for you to try on your side. This makes me think that the coordinate of the spline GO is not issue, at least not in such value ranges.

The screenshots you attached to your post show two splines that are not superposed. I get that this is to make the screenshots easiest to understand, but I am curious in the result of tests where the two splines are exactly superposing.

If you open the attached scene, you will find a GO named TangentTester. You can see that whatever the spline you assign as an input for the test the tangent is the same.

Let me know if you manage to reproduce the issue with superposing splines.

Have a nice weekend, and happy new year.

Thanks so much for the example it was tremendously helpful - based on your code I cleaned up:

Code:
Vector3 mvector = Spline.GetNearestPoint(mRigidBody.transform.position, Space.World);
Vector3 p;
BikeTF = Spline.GetNearestPointTF(mvector,
    out p
);

to:
             
Code:
  Vector3 p;

float BikeTF = Spline.GetNearestPointTF(transform.position, out p, Space.World);

and it fixed everything! Thanks! Happy new year!!! ^0^
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How can I find the point on the spline after applying with offset angle+radius? Chanon 1 5 10-01-2022, 11:50 AM
Last Post: _Aka_
  Make hard angle cll3m 5 1,402 07-01-2021, 04:06 PM
Last Post: _Aka_
Wink How to generate right angle road oscar.ken 6 4,687 04-30-2020, 05:38 PM
Last Post: ThomasTheTank
  Twisted mesh at corner on linear path JLeonard 0 2,176 02-24-2017, 04:42 PM
Last Post: JLeonard

Forum Jump: