Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Closest Point on Spline (+Offset) to some World Position
#1
Hi,

I'm working on a driving action game. I'd been using Curvy to control the cars along the spline, but for several reasons, I switched to PhysX based cars. I finally have them working the way I want on straight roads, but of course I want curvy roads in my game, and I'm using Curvy to do that Smile

For this reason I'm wondering how it might be possible to get the closest point on the road spline to some carTransform.position. My roads are curvy spline based and use a coordinate system of normal Curvy Position + and offset (called Lane Position). The offset is very important to this because for lane tracking of course.

So in the image below, imagine that green car squiggle is a gameobject not controlled by a Curvy controller. However I want to know its current "Road Position"
Assuming a Lane width of 3 (so range of -6 to 6 of Lane position) that car would be at SplinePosition "P" and LanePosition 1.5f. (just eyeballing it)

How can I find this out programatically given the car's transform position?


[Image: QB7VYkx.png]


If I can figure this out, I'll get a major breakthrough in being able to use curved roads with my PhysX based cars Smile
Reply
#2
Hi,
This should answer your question:
Code:
Vector3 P;
float carTf = yourSpline.GetNearestPointTF(carTransform.position, out P);
Quaternion splineOrientation = yourSpline.GetOrientationFast(carTf);
//the projection is to handle possible scenarios where the car is not on the road
Vector3 carProjectionToRoadCenter = Vector3.ProjectOnPlane((carTransform.position - P), splineOrientation * Vector3.up);
float lanePosition = Vector3.Dot(carProjectionToRoadCenter, splineOrientation * Vector3.right);
Please consider leaving a review for Curvy. This will help a lot keeping Curvy relevant in the eyes of the Asset Store algorithm.
Reply
#3
(01-23-2018, 01:03 PM)_Aka_ Wrote: Hi,
This should answer your question:
Code:
Vector3 P;
float carTf = yourSpline.GetNearestPointTF(carTransform.position, out P);
Quaternion splineOrientation = yourSpline.GetOrientationFast(carTf);
//the projection is to handle possible scenarios where the car is not on the road
Vector3 carProjectionToRoadCenter = Vector3.ProjectOnPlane((carTransform.position - P), splineOrientation * Vector3.up);
float lanePosition = Vector3.Dot(carProjectionToRoadCenter, splineOrientation * Vector3.right);



Awesome, thank you! Makes sense to me. Can GetNearestPointTF be called safely during FixedUpdate? With Upwards of 20 cars calling it?
Reply
#4
20 calls per frame should not create a performance issue.

If you end up in the future with GetNearestPointTF being a performance bottleneck, keep in mind that the there are overrides of this method that allow you to search for the nearest point not in all the spline's segments, but only in subset of the spline's segments. In your case, and as long as a car does not teleport, you can safely assume that, if a car was in a segment X this frame, it will the next frame either in the same segment X, or in one of X neighbors.
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
(01-23-2018, 05:12 PM)_Aka_ Wrote: 20 calls per frame should not create a performance issue.

If you end up in the future with GetNearestPointTF being a performance bottleneck, keep in mind that the there are overrides of this method that allow you to search for the nearest point not in all the spline's segments, but only in subset of the spline's segments. In your case, and as long as a car does not teleport, you can safely assume that, if a car was in a segment X this frame, it will the next frame either in the same segment X, or in one of X neighbors.

Awesome. You're so helpful! I also am looking at 05_NearestPoint. I will try this on my new car with a curved track and post a video update. Right after I leave my review Big Grin
Reply
#6
Thanks a lot Smile I wish you all the best with your game, and am curious to see the end result.
Please consider leaving a review for Curvy. This will help a lot keeping Curvy relevant in the eyes of the Asset Store algorithm.
Reply
#7
EDIT: Fixed the issue, but leaving here just in case someone else runs into it

Hey Aka,

So the lane position code works great. I'm having a bit of an issue with the GetNearestPointTF though. Just using this code:
[Image: 93fF2NA.png]


I'm doing a straight road starting at z = 0 and going to z = 1000 for just a validity test. It seems like carTf is not increasing linearly. CarTF starts out higher than the position on the road, at z=500 it matches up, and then the back half, the carTf is lower than the actual road position, and lines up at the very end.

I don't have the car starting at z=0 but I imagine it would match up there too, and then increase faster.

I took a video here to kind of show what's going on:
https://youtu.be/UMbNZI5NZVY


Hopefully this is just in "stupid mistake on my part territory" but the code is one line and from you, but maybe I missed a spline setting somewhere :p

Thank you!

And yes, I have a feeling that I'll be very active on these forums. I don't generally like to use 3rd party solutions for core systems (other than one-off art or FX things) because stuff can get abandoned etc (I'm SO happy with how you guys decided to transition) - but Curvy fits the game so well and will be an integral part of the game. I'm happy to include it in media / promotions , trailers "Made Possible With Curvy" etc and shout it from the rooftops in exchange for support or possibly maybe custom features (can't think of any atm, but I'm sure I will during development)

[Image: 2Kg3IyA.png]
[Image: CjJ3qTF.jpg]
Reply
#8
(01-25-2018, 02:15 AM)nomadigi Wrote: It seems like carTf is not increasing linearly.

It is indeed not linear in most cases, and this is normal.
If your are curious about why, take a look at this Wikipedia page, and notice how, in most cases, the point travels with different speeds depending if it is around the spline middle or around it's end.

So, your solution (setting the spline to linear) is not really one, since it will work only on linear splines. If you have a curved spline, you will meet the same problem again.

The real issue comes from how you define your car position:
Code:
float roadPosition = carTf * RoadSpline.Length;
It should be instead
Code:
float roadPosition = RoadSpline.TFToDistance(carTf)

Splines have often different versions of the same methods, one taking TFs as an input, and the other taking distances.

Let me know if this doesn't help.
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
Big Grin 
Thanks for replying, looks like I was mistaken after all. As soon as I put the curve in the road I would have been stumped again Tongue

The good news is TFtoDistance was the ticket Big Grin can add some logic to lerp my wheel turning a bit to smooth it out, but otherwise this is behaving beautifully! 


AI Vehicle now following a Curvy based road spline but still using 100% Unity wheel PhysX to move (as opposed to spline controller). All movement is AI driven with the exception of developer picking desired lane (right or left).

https://youtu.be/T7eyxjairsE
Reply
#10
And now I can do stuff like this without adding any more code Smile

https://youtu.be/16BORnCdRJs
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
Bug Changing spline connection in inspector causes splines to revert to defaults lacota 3 6 03-18-2024, 07:55 PM
Last Post: _Aka_
  GO can't fit end of the spline GameDeveloperek4123 3 13 03-04-2024, 11:06 AM
Last Post: _Aka_
  Avoiding runtime GC allocations on control point position change Ell223 8 18 02-24-2024, 10:43 AM
Last Post: _Aka_
  Keeping a fixed spline length jh092 3 16 02-21-2024, 06:25 AM
Last Post: Primrose44

Forum Jump: