Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
To dynamic generate the connection between paths
#1
Hi, right now I'm trying to implement the feature to allow "SpineController" switch between 2 "CurvySpline"
problem was the timing should define by the NPC itself.

so the connection wasn't predefined on scene yet, how can I achieve that feature ?

it's my first time try to use this plugin, but I do have some experience on bezier curve.
here is the project I'm working on the yellow gizmos line appear on scene was the feature I'm talking about.
any idea where should I start ?


the logic in video as follow.

  1. Assume we got 2 CurvySpline A & B
  2. Get ship current position & rotation on Curve A.
  3. project direction vector based on ship's velocity & heading, and use that point as reference to locate the closest point on Curve B.
    similar to CurvySpline.GetNearestPointTF()
  4. Generate tangent via subdividing. (Not sure how to do that in Curvy)
  5. Travel on temporary path until reaching 100%, switch to Curve B. (Not sure how to do that in Curvy)
Reply
#2
okay, I found the function to generate curve at runtime..
here is the shadow code that I think will work

Code:
Transform m_Ship = null; // assume we got this
CurvySpline curveA = null; // assume we got this
CurvySpline curveB = null; // assume we got this

float startTF = curveA.GetNearestPointTF(m_Ship.position, Space.World);
Vector3 startPoint = curveA.GetApproximation(startTF, startTF, true, Space.World)[0]; // Huh ? how to get the closer sample point ?
Vector3 startTangent = m_Ship.forward * 2f; // bias
           
float endTF = curveB.GetNearestPointTF(startTangent, Space.World);
Vector3 endPoint = curveA.GetApproximation(endTF, endTF, true, Space.World)[0];
Vector3 endTangent = curveA.GetOrientationFast(endTF, false, Space.World) * Vector3.forward;

var curve = CurvySpline.Create();
var start = curve.Add(startPoint, Space.World);
start.HandleOut = start.transform.InverseTransformPoint(startTangent); // is that the right way to convert local space ?
var end = curve.Add(endPoint, Space.World);
end.HandleIn = endTangent;


so... is that all I need ?
Question about "curveA.GetApproximation()" I expect will get the closest point instead of array of Vector3, am I doing it wrong ?
since I got startFT from "GetNearestPointTF"
... continue testing.
Reply
#3
Hi,
  1. Here is an example of code, as seen in the example scene 05_NearestPoint, to get the nearest point on a spline:
    float nearestTF = Spline.GetNearestPointTF(Lookup.position, Space.World);
    transform.position = Spline.Interpolate(nearestTF, Space.World);
    If you want the position of a sample point, in opposition of an exacte position on the spline, use InterpolateFast instead of Interpolate.
  2. You can use the HandleOutPosition and HandleInPosition to set the handles in world coordinates.
  3. I have a GetNearestPointTF that works for rays, but it is not optimized nor properly tested. I attached the needed files to this post. Might nor compile with the latest version of Curvy. If so, fixing the compiler errors should not be difficult.
  4. Not sure about what you mean in your point 4. By creating a spline Curvy aytomatically generates tangents, so you don't have to do it yourself.
  5. If you use SplineController, then you can use the SwitchTo method, or get inspiration from its implementation, to switch between two splines.
Was everything clear?


Attached Files
.cs   CurvySplineSegment_Ray.cs (Size: 2.44 KB / Downloads: 2)
.cs   CurvySpline_Ray.cs (Size: 3.13 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
#4
(08-07-2020, 02:47 PM)_Aka_ Wrote: Hi,
  1. Here is an example of code, as seen in the example scene 05_NearestPoint, to get the nearest point on a spline:
    float nearestTF = Spline.GetNearestPointTF(Lookup.position, Space.World);
    transform.position = Spline.Interpolate(nearestTF, Space.World);
    If you want the position of a sample point, in opposition of an exacte position on the spline, use InterpolateFast instead of Interpolate.
  2. You can use the HandleOutPosition and HandleInPosition to set the handles in world coordinates.
  3. I have a GetNearestPointTF that works for rays, but it is not optimized nor properly tested. I attached the needed files to this post. Might nor compile with the latest version of Curvy. If so, fixing the compiler errors should not be difficult.
  4. Not sure about what you mean in your point 4. By creating a spline Curvy aytomatically generates tangents, so you don't have to do it yourself.
  5. If you use SplineController, then you can use the SwitchTo method, or get inspiration from its implementation, to switch between two splines.
Was everything clear?

thanks for quick reply Heart , I miss the "Interpolate" API, that's what I need for tangent info.
(3) was a cool stuff, I'm sure it will be handy
well, forget about (4) you already answer my question on (1) & (2)
btw, (5) "SwitchTo" method looks like it was the feature I wanted to implement, will try to use that method first.

Still cleaning up my code and prepare to migrate into curvy, but based on your answer write following shadow code,
just to make sure I didn't misunderstand anything.

Code:
Transform m_Ship = null; // assume we got this
CurvySpline curveA = null; // assume we got this
CurvySpline curveB = null; // assume we got this

// point on travel path.
float startTF = curveA.GetNearestPointTF(m_Ship.position, Space.World);
curveA.InterpolateAndGetTangentFast(startTF, out Vector3 startPoint, out Vector3 startTangent, Space.World);

// point to switch path.
float endTF = curveB.GetNearestPointTF(startTangent, Space.World);
curveB.InterpolateAndGetTangentFast(endTF, out Vector3 endPoint, out Vector3 endTangent, Space.World);

// Generate path !
var curve = CurvySpline.Create();
var start = curve.Add(startPoint, Space.World);
var end = curve.Add(endPoint, Space.World);
// define tangent(s) from start to end.
start.HandleOutPosition = startTangent;
end.HandleInPosition = endTangent;
Reply
#5
start.HandleOut should be defined as
start.HandleOut = curve.transform.InverseTransformDirection(startTangent);
Same for end.HandleIn
Also, you probably want to negate end.HandleIn
That's it.
If and when you feel like it, please leave a review for the asset, that helps a lot.
Have a nice day
Please consider leaving a review for Curvy. This will help a lot keeping Curvy relevant in the eyes of the Asset Store algorithm.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Connection survives spline duplication rmrmrm 7 1,071 05-22-2020, 01:28 PM
Last Post: _Aka_
  Gradually rendering paths Ærilwentar 3 579 05-08-2020, 11:03 AM
Last Post: _Aka_
Wink How to generate right angle road oscar.ken 6 2,210 04-30-2020, 05:38 PM
Last Post: ThomasTheTank
  Make connection between 2 control points dazz777 11 2,414 04-17-2020, 01:37 PM
Last Post: _Aka_

Forum Jump: