Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Dreamteck Splines - Powerful and Flexible Spline Solution

Discussion in 'Assets and Asset Store' started by Dreamteck, May 11, 2016.

  1. cristims

    cristims

    Joined:
    Dec 21, 2012
    Posts:
    24
    Thank you for your reply. I will check the samples asap.

    I also want to ask you, if you have the time of course, to add more exposed methods to the follower script. My C# skills are... mediocre at best, and I cannot seem to "hack" your scripts to do what I want/need.

    For example, I need a method to assign from code a particular spline to a newly spawned agent. Something like "followerScript.assignSpline (game object)". And maybe a .moveToSpline() and a simple .Start/Stop.


    For now is great how it is, but I will need to dig deeper in the near future.
    Thank you again for the reply.
     
  2. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    You are welcome!
    All of this is already in and described in the API reference.

    SplineFollower follower = GetComponent<SplineFollower>();

    To set the spline of the follower: follower.computer = yourDesiredComputer;
    To set the percent (0-1) along the spline: follower.SetPercent(yourDesiredPercent);
    To set distance in world units along the spline: follower.SetDistance(length);

    For start/stop:
    follower.autoFollow = true;
    follower.autoFollow = false;
     
    Last edited: May 5, 2019
  3. Amatobahn

    Amatobahn

    Joined:
    Aug 8, 2012
    Posts:
    21
    Hello. I've been trying to figure out the methodology for using a Camera.ScreenpointToRay() hit point on the spline (tube generator + mesh collider) to get the 0-1 position of the hit on the spline itself. [Imagine a line graph] I've looked into SplineComputer.Travel(), but when a spline is not linear from left to right, I won't ever return a proper position. Is there a better approach to this or should I continue exploring using SplineComputer.Travel?

    Thanks
     
  4. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    If I understood correctly, you need to use the Project method in order to convert the world hit point from the raycast to a 0-1 percent on the spline. Travel moves along a spline using a start percent a d a world distance.
     
  5. Amatobahn

    Amatobahn

    Joined:
    Aug 8, 2012
    Posts:
    21
    Ah-ha! I was looking at the spline computer portion of the docs and not the subset Spline - Perfect. Thanks!
     
  6. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    You shouldn't use Spline.Project if you are using a SplineComputer. The SplineComputer also has a Project method and the SplineUser has one as well. So SplineComputer.Project should do the trick.
     
  7. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    Anyone working on something interesting using Dreamteck Splines? We're making a video and would love to include some cool footage and give credit to the creators.
     
  8. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    215
    Hopefully I'll have a nice video ready for the next time you are making a video :)

    It should look fantastic
     
    Dreamteck likes this.
  9. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    We will be releasing the new version hopefully mid-june so you still have time!
     
  10. Avinash

    Avinash

    Joined:
    Mar 25, 2010
    Posts:
    7
    @Dreamteck how can i change the motion postion offset value , during runtime ?
     
  11. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    Set GetComponent<SplineFollower>().motion.offset during runtime.
     
  12. Antony-Blackett

    Antony-Blackett

    Joined:
    Feb 15, 2011
    Posts:
    1,282
    Hi. I was wondering how the mesh extrusion handles hard corners like ones on a linear spline? I’m looking for a solution to build straight walls with sharp corners but so far all spline tools end up with a twisted mess of a mesh at these points.

    I’m especially interested in the mesh extruder that can remove inside faces. I’ll likely only be using an object not much more complex than a cube.

    Edit:
    Yeah... So here's what I didn't want to see with the tube generator.
    I'd expect the tube to stay 1 width wide at all points along the spline, so at the corners you need to extend the width depending on the corner angle (there's probably some extra math involved than just that).

    I also can't see any way to make the tube have nonsmooth normals. Is there a way to do that?
    Screen Shot 2019-05-27 at 5.29.17 PM.png
     
    Last edited: May 27, 2019
  13. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    This is how linear splines work unfortunately. You can't preserve the radius of your geometry because it is just not mathematically possible. We are currently working on an update that will improve the corner angles for linear splines but there will always be distortion because the vertices at the angle points would be rotated a little.
     
  14. wesley_unity341

    wesley_unity341

    Joined:
    Dec 14, 2018
    Posts:
    9
    Maybe I am missing something but is there a way to just use the global Y-Axis as the normal for geometry/path generation? Rather than the spline normals, which rotates the geometry naturally.
     
  15. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    Not really. Why do you need to do this? Are you after some sort of a skew effect? You can Duplicate the TubeGenerator class and replace the normal direction there with "Vector3.up" and you should get that effect.
     
  16. wesley_unity341

    wesley_unity341

    Joined:
    Dec 14, 2018
    Posts:
    9
    We're using the normals of the spline to influence a hinge joint travelling along the spline, but prefer the generated geometry to just point straight up.
     
  17. Antony-Blackett

    Antony-Blackett

    Joined:
    Feb 15, 2011
    Posts:
    1,282
    So it seems it's not mathematically impossible. Screen Shot 2019-06-01 at 5.00.01 PM.png

    I had a bit of spare time today to work on my linear spline path problem and I've come up with this solution that seems like it'll work. I've got it going for a simple case, I'll try extend it to all cases before sharing the generator.
     
  18. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    That's interesting! What approach are you using? You don't seem to be just averaging directions but also increasing vertex offsets at corners. Would that work in 3D as well?
     
  19. Antony-Blackett

    Antony-Blackett

    Joined:
    Feb 15, 2011
    Posts:
    1,282
    It should. That’s the next task when i get a minute to work on it.
     
  20. Antony-Blackett

    Antony-Blackett

    Joined:
    Feb 15, 2011
    Posts:
    1,282
    Here the code i've come up with so far. it's a bit messy and can probably be simplified a lot but anyway, so you have an idea about how i'm doing it:

    The idea behind the code is to use line plane intersections to figure out where the verts should be.

    Issues:
    - If a spline makes a very acute angle turn the geometry is wrong.
    - Rotation property only works at 90 degree increments.
    - I've only done the path generator so far, other generators will then not match the generation for the path such as if you use a path to draw a line around a surface, like i want to do with walls, then the surface (when using expand) and the outer path edges do not lineup.

    The idea should work for pipes, I'll attempt that next and i think I'll also update the surface generator to match as well when using the 'expand' property.

    Replace your path generator's GenerateVertices with this:

    Code (csharp):
    1.  
    2.         Vector3 GetRight( Vector3 direction, Vector3 normal )
    3.         {
    4.             if( normal == direction )
    5.             {
    6.                 if( normal == Vector3.up ) return Vector3.right;
    7.                 else return Vector3.Cross( Vector3.up, direction ).normalized;
    8.             }
    9.             return Vector3.Cross( normal, direction ).normalized;
    10.         }
    11.  
    12.  
    13.         void GenerateVertices()
    14.         {
    15.             int vertexCount = (_slices + 1) * clippedSamples.Length;
    16.             AllocateMesh( vertexCount, _slices * (clippedSamples.Length - 1) * 6 );
    17.             int vertexIndex = 0;
    18.  
    19.             ResetUVDistance();
    20.  
    21.             if( clippedSamples.Length < 1 )
    22.             {
    23.                 return;
    24.             }
    25.  
    26.             for( int i = 0; i < clippedSamples.Length; i++ )
    27.             {
    28.                 Vector3 lp = clippedSamples[i].position;
    29.                 Vector3 p = clippedSamples[i].position;
    30.                 Vector3 np = clippedSamples[i].position;
    31.                 Vector3 segment1 = (p + clippedSamples[i].direction).normalized;
    32.  
    33.                 if( i > 0 )
    34.                 {
    35.                     lp = clippedSamples[i - 1].position;
    36.                     segment1 = (p - lp).normalized;
    37.                 }
    38.  
    39.                 if( clippedSamples.Length > i + 1 )
    40.                 {
    41.                     np = clippedSamples[i + 1].position;
    42.                 }
    43.                 else if( rootUser.computer.isClosed )
    44.                 {
    45.                     np = clippedSamples[1].position; // loop
    46.                 }
    47.                 else
    48.                 {
    49.                     np = clippedSamples[i].position + segment1; // pretend line continues in the same diretion
    50.                 }
    51.                 Vector3 segment2 = (np - p).normalized;
    52.  
    53.                 if( i == 0 )
    54.                 {
    55.                     if( rootUser.computer.isClosed )
    56.                     {
    57.                         lp = clippedSamples[ clippedSamples.Length-2].position; // loop
    58.                         segment1 = (p - lp).normalized;
    59.                     }
    60.                     else
    61.                     {
    62.                         lp = clippedSamples[i].position - segment2; // pretend line continues in the same diretion
    63.                         segment1 = (p - lp).normalized;
    64.                     }
    65.                 }
    66.  
    67.                 float width = size * clippedSamples[i].size;
    68.  
    69.                 Vector3 segment1Normal = GetRight( segment1, clippedSamples[i].normal );
    70.                 Vector3 segment2Normal = GetRight( segment2, clippedSamples[i].normal );
    71.                 Vector3 Segment1RightPoint = p + (segment1Normal * width * 0.5f);
    72.                 Vector3 Segment2RightPoint = p + (segment2Normal * width * 0.5f);
    73.                 Vector3 Segment2RightPlaneNormal = -segment2Normal;
    74.  
    75.                 Vector3 vertRight = p + segment1Normal * width * 0.5f;
    76.                 float dotSegment1And2 = Vector3.Dot( segment1, segment2 );
    77.                 if( Mathf.Abs( dotSegment1And2 ) < 0.999f )
    78.                 {
    79.                     vertRight = MathHelper.LinePlaneIntersection( Segment1RightPoint, segment1, Segment2RightPoint, Segment2RightPlaneNormal );
    80.                 }
    81.  
    82.                 Vector3 segment1LeftPoint = p - (segment1Normal * width * 0.5f);
    83.                 Vector3 segment2LeftPoint = p - (segment2Normal * width * 0.5f);
    84.                 Vector3 Segment2LeftPlaneNormal = segment2Normal;
    85.  
    86.                 Vector3 vertLeft = p - segment1Normal * width * 0.5f;
    87.                 if( Mathf.Abs( dotSegment1And2 ) < 0.999f )
    88.                 {
    89.                     vertLeft = MathHelper.LinePlaneIntersection( segment1LeftPoint, segment1, segment2LeftPoint, Segment2LeftPlaneNormal );
    90.                 }
    91.  
    92.                 Vector3 center = (vertRight + vertLeft) * 0.5f;
    93.                 Vector3 lastVertPos = Vector3.zero;
    94.                 float fullSize = Vector3.Distance( vertLeft, vertRight );
    95.                 Vector3 right = (vertRight - vertLeft).normalized;
    96.  
    97.                 if( offset != Vector3.zero ) center += offset.x * right * fullSize + offset.y * clippedSamples[i].normal + offset.z * clippedSamples[i].direction;
    98.  
    99.                 float t = Mathf.InverseLerp( 0, 90, 90 - Mathf.Abs( rotation ) );
    100.                 fullSize = Mathf.Lerp( width, fullSize, t ); // this needs work
    101.  
    102.                 Quaternion rot = Quaternion.AngleAxis( rotation, GetRight( (vertRight-vertLeft).normalized, clippedSamples[i].normal ) );
    103.                 if( uvMode == UVMode.UniformClamp || uvMode == UVMode.UniformClip ) AddUVDistance( i );
    104.                 for( int n = 0; n < _slices + 1; n++ )
    105.                 {
    106.                     float slicePercent = ((float)n / _slices);
    107.                     float shapeEval = 0f;
    108.                     if( _useShapeCurve ) shapeEval = _shape.Evaluate( slicePercent );
    109.                     tsMesh.vertices[vertexIndex] = center + rot * right * fullSize * 0.5f - rot * right * fullSize * slicePercent + rot * clippedSamples[i].normal * shapeEval * _shapeExposure;
    110.                     CalculateUVs( clippedSamples[i].percent, 1f - slicePercent );
    111.                     tsMesh.uv[vertexIndex] = Vector2.one * 0.5f + (Vector2)(Quaternion.AngleAxis( uvRotation, Vector3.forward ) * (Vector2.one * 0.5f - uvs));
    112.                     if( _slices > 1 )
    113.                     {
    114.                         if( n < _slices )
    115.                         {
    116.                             float forwardPercent = ((float)(n + 1) / _slices);
    117.                             shapeEval = 0f;
    118.                             if( _useShapeCurve ) shapeEval = _shape.Evaluate( forwardPercent );
    119.                             Vector3 nextVertPos = center + rot * right * fullSize * 0.5f - rot * right * fullSize * forwardPercent + rot * clippedSamples[i].normal * shapeEval * _shapeExposure;
    120.                             Vector3 cross1 = -Vector3.Cross( clippedSamples[i].direction, nextVertPos - tsMesh.vertices[vertexIndex] ).normalized;
    121.  
    122.                             if( n > 0 )
    123.                             {
    124.                                 Vector3 cross2 = -Vector3.Cross( clippedSamples[i].direction, tsMesh.vertices[vertexIndex] - lastVertPos ).normalized;
    125.                                 tsMesh.normals[vertexIndex] = Vector3.Slerp( cross1, cross2, 0.5f );
    126.                             }
    127.                             else tsMesh.normals[vertexIndex] = cross1;
    128.                         }
    129.                         else tsMesh.normals[vertexIndex] = -Vector3.Cross( clippedSamples[i].direction, tsMesh.vertices[vertexIndex] - lastVertPos ).normalized;
    130.                     }
    131.                     else
    132.                     {
    133.                         tsMesh.normals[vertexIndex] = clippedSamples[i].normal;
    134.                         if( rotation != 0f ) tsMesh.normals[vertexIndex] = rot * tsMesh.normals[vertexIndex];
    135.                     }
    136.                     tsMesh.colors[vertexIndex] = clippedSamples[i].color * color;
    137.                     lastVertPos = tsMesh.vertices[vertexIndex];
    138.                     vertexIndex++;
    139.                 }
    140.             }
    141.         }
    142.  
    143.  
    you will also need this static function:

    Code (csharp):
    1.  
    2. public static class MathHelper
    3. {
    4.     public static Vector3 LinePlaneIntersection( Vector3 rayOrigin, Vector3 rayDirection, Vector3 planePoint, Vector3 planeNormal )
    5.     {
    6.         Vector3 diff = rayOrigin - planePoint;
    7.         float prod1 = Vector3.Dot( diff, planeNormal );
    8.         float prod2 = Vector3.Dot( rayDirection, planeNormal );
    9.         float prod3 = prod1 / prod2;
    10.         return rayOrigin - rayDirection * prod3;
    11.     }
    12. }
    13.  
    14.  

    Edit:
    And working on it some more, here's a simpler solution using Trig

    Code (csharp):
    1.  
    2.         void GenerateVertices()
    3.         {
    4.             int vertexCount = (_slices + 1) * clippedSamples.Length;
    5.             AllocateMesh( vertexCount, _slices * (clippedSamples.Length - 1) * 6 );
    6.             int vertexIndex = 0;
    7.  
    8.             ResetUVDistance();
    9.  
    10.             if( clippedSamples.Length < 1 )
    11.             {
    12.                 return;
    13.             }
    14.  
    15.             for( int i = 0; i < clippedSamples.Length; i++ )
    16.             {
    17.                 Vector3 lp = clippedSamples[i].position;
    18.                 Vector3 p = clippedSamples[i].position;
    19.                 Vector3 np = clippedSamples[i].position;
    20.                 Vector3 segment1 = (p + clippedSamples[i].direction).normalized;
    21.  
    22.                 if( i > 0 )
    23.                 {
    24.                     lp = clippedSamples[i - 1].position;
    25.                     segment1 = (p - lp).normalized;
    26.                 }
    27.  
    28.                 if( clippedSamples.Length > i + 1 )
    29.                 {
    30.                     np = clippedSamples[i + 1].position;
    31.                 }
    32.                 else if( rootUser.computer.isClosed )
    33.                 {
    34.                     np = clippedSamples[1].position; // loop
    35.                 }
    36.                 else
    37.                 {
    38.                     np = clippedSamples[i].position + segment1; // pretend line continues in the same diretion
    39.                 }
    40.                 Vector3 segment2 = (np - p).normalized;
    41.  
    42.                 if( i == 0 )
    43.                 {
    44.                     if( rootUser.computer.isClosed )
    45.                     {
    46.                         lp = clippedSamples[clippedSamples.Length - 2].position; // pretend line continues in the same diretion
    47.                         segment1 = (p - lp).normalized;
    48.                     }
    49.                     else
    50.                     {
    51.                         lp = clippedSamples[i].position - segment2; // pretend line continues in the same diretion
    52.                         segment1 = (p - lp).normalized;
    53.                     }
    54.                 }
    55.  
    56.                 segment1 = Vector3.ProjectOnPlane( segment1, clippedSamples[i].normal ).normalized;
    57.                 segment2 = Vector3.ProjectOnPlane( segment2, clippedSamples[i].normal ).normalized;
    58.  
    59.                 Vector3 direction = (segment1 + segment2).normalized;
    60.                 Quaternion rot = Quaternion.AngleAxis( rotation, direction );
    61.                 Vector3 normal = clippedSamples[i].normal;
    62.                 Vector3 right = GetRight( direction, normal );
    63.  
    64.                 float angle = (180-Vector3.Angle( Vector3.ProjectOnPlane( segment1 , rot * normal ), Vector3.ProjectOnPlane( segment2, rot * normal ) ) ) *0.5f;
    65.                 float sizeAngleScalar = 1.0f/Mathf.Sin( angle * Mathf.Deg2Rad);
    66.                 Vector3 center = Vector3.zero;
    67.                 try
    68.                 {
    69.                     center = clippedSamples[i].position;
    70.                 }
    71.                 catch( System.Exception ex ) { Debug.Log( ex.Message + " for i = " + i ); return; }
    72.  
    73.                 float angleForOffset = (180 - Vector3.Angle( Vector3.ProjectOnPlane( segment1, normal ), Vector3.ProjectOnPlane( segment2, normal ) )) * 0.5f;
    74.                 float sizeAngleScalarForOffset = 1.0f / Mathf.Sin( angleForOffset * Mathf.Deg2Rad );
    75.                 if( offset != Vector3.zero ) center += offset.x * sizeAngleScalarForOffset * right + offset.y * clippedSamples[i].normal + offset.z * direction;
    76.  
    77.                 Vector3 lastVertPos = Vector3.zero;
    78.  
    79.                 float fullSize = size * clippedSamples[i].size * sizeAngleScalar;
    80.  
    81.                 if( uvMode == UVMode.UniformClamp || uvMode == UVMode.UniformClip ) AddUVDistance( i );
    82.                 for( int n = 0; n < _slices + 1; n++ )
    83.                 {
    84.                     float slicePercent = ((float)n / _slices);
    85.                     float shapeEval = 0f;
    86.                     if( _useShapeCurve ) shapeEval = _shape.Evaluate( slicePercent );
    87.                     tsMesh.vertices[vertexIndex] = center + rot * right * fullSize * 0.5f - rot * right * fullSize * slicePercent + rot * clippedSamples[i].normal * shapeEval * _shapeExposure;
    88.                     CalculateUVs( clippedSamples[i].percent, 1f - slicePercent );
    89.                     tsMesh.uv[vertexIndex] = Vector2.one * 0.5f + (Vector2)(Quaternion.AngleAxis( uvRotation, Vector3.forward ) * (Vector2.one * 0.5f - uvs));
    90.                     if( _slices > 1 )
    91.                     {
    92.                         if( n < _slices )
    93.                         {
    94.                             float forwardPercent = ((float)(n + 1) / _slices);
    95.                             shapeEval = 0f;
    96.                             if( _useShapeCurve ) shapeEval = _shape.Evaluate( forwardPercent );
    97.                             Vector3 nextVertPos = center + rot * right * fullSize * 0.5f - rot * right * fullSize * forwardPercent + rot * clippedSamples[i].normal * shapeEval * _shapeExposure;
    98.                             Vector3 cross1 = -Vector3.Cross( direction, nextVertPos - tsMesh.vertices[vertexIndex] ).normalized;
    99.  
    100.                             if( n > 0 )
    101.                             {
    102.                                 Vector3 cross2 = -Vector3.Cross( direction, tsMesh.vertices[vertexIndex] - lastVertPos ).normalized;
    103.                                 tsMesh.normals[vertexIndex] = Vector3.Slerp( cross1, cross2, 0.5f );
    104.                             }
    105.                             else tsMesh.normals[vertexIndex] = cross1;
    106.                         }
    107.                         else tsMesh.normals[vertexIndex] = -Vector3.Cross( direction, tsMesh.vertices[vertexIndex] - lastVertPos ).normalized;
    108.                     }
    109.                     else
    110.                     {
    111.                         tsMesh.normals[vertexIndex] = clippedSamples[i].normal;
    112.                         if( rotation != 0f ) tsMesh.normals[vertexIndex] = rot * tsMesh.normals[vertexIndex];
    113.                     }
    114.                     tsMesh.colors[vertexIndex] = clippedSamples[i].color * color;
    115.                     lastVertPos = tsMesh.vertices[vertexIndex];
    116.                     vertexIndex++;
    117.                 }
    118.             }
    119.         }
    120.  
    It's not quite perfect but that's the best i can do while still keeping offset and rotation working as they were
     
    Last edited: Jun 3, 2019
    Dreamteck likes this.
  21. Casss

    Casss

    Joined:
    Dec 13, 2016
    Posts:
    3
    Can you upload an exemple with Rigibody Car like in your video tutorial?
     
  22. alanmthomas

    alanmthomas

    Joined:
    Sep 7, 2015
    Posts:
    149
    I just updated my Unity project and got a window about version 2 coming on June 15. Any update on that?
     
  23. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    We are delaying the new version. We want to make sure everything runs smoothly and are providing a quality product + quality documentation. We apologize for the delay.
    We are also still gathering videos from projects made with Dreamteck Splines for the upcoming new trailer. This is also going very slowly. We know that there are tons of projects made with this tool but for some reason nobody appears to have footage.
     
  24. MorbidDesign

    MorbidDesign

    Joined:
    Jun 4, 2017
    Posts:
    4
    Hi there! Congratulations on this awesome tool!

    I'm facing a problem and I'm not being able to find the solution. I have a road already generated, and I have placed a lot of spline points along it (Surface mode). But the inclinations on the road make my car to fly and go below the asphalt... Is there some function to create points between points along the mesh? I'm just figuring out how to achieve this by code, but an automatic function would save me a lot of time... ;)

    BTW, I'm moving the Transform, not using physics.

    Cheers!
     
  25. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    Yes, when in point creation mode, choose the Insert point mode - this will let you add points in between other points.
     
  26. MorbidDesign

    MorbidDesign

    Joined:
    Jun 4, 2017
    Posts:
    4
    But doing this won't insert a point in Surface mode, and won't change the Y-axis of the spline automatically.. And if the line between two points is below the road because of a little mountain, the spline will remain there, no matter how many points I insert. Am I right?
     
  27. ariel-m

    ariel-m

    Joined:
    Jan 29, 2018
    Posts:
    1
    Hello! We are working on a mid-big project here, and we are having some problems with splines and the new prefab system!
    Idk if anyone adressed it already, i tried looking some pages before this date, and none seems to touch the subject, but when I add a spline on a prefab, and put multiple prefabs on the scene, the followers seems to get the first prefab. All of them follow the same spline.
    That is, until I click on the follower or the computer, and suddently it recalculates correctly!

    Any idea if this will be fixed, or what may be causing it?

    Love the plugin! Congrats!

    Edit:
    I did find a way around it! I put a new script with reference to the computer, and on start i do a rebuild(). That seems to do the trick, altho its something that might be risky, i dont know if i can use that method this way. Its working so far, ill let u guys tell me a better way to go about this!
     
    Last edited: Jul 19, 2019
  28. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    Dreamteck Splines 2 has a method for moving points along a surface but we need some more time until we can release it to the public. For now this is not possible out-of-the-box.
     
  29. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    Calling rebuild is fine - you don't have to worry about it.
     
  30. Lukas_v11

    Lukas_v11

    Joined:
    Mar 17, 2016
    Posts:
    6
    Hi guys

    Great asset. But i have some problem to move an object with percent value on the spline. I have imported the spline via SVG importer. Please see the screenshot attached.

    The object travel speed is slower on the corners and faster in between. How can i achieve a uniform speed when positioning with percent value?

    And how can i read the current position back in percent value?
    Is SplineFollower.result.percent correct?

    Thank you.
     

    Attached Files:

  31. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    Use the Travel method to calculate a percent for uniform movement.
     
  32. Lukas_v11

    Lukas_v11

    Joined:
    Mar 17, 2016
    Posts:
    6
    Thank you, but can you please be a bit more specific?

    I have a spline. The total distance is unknown. I want to move a game-object from 0 to 1.

    Thank you very much!
     
  33. jeffweber

    jeffweber

    Joined:
    Dec 17, 2009
    Posts:
    555
    EvaluatePosition is not returning what I expect when I have more than 2 nodes in my spline and they are not uniformly spaced.

    Here is the code I'm using:
    Code (CSharp):
    1. var position = splineUser.EvaluatePosition(.5f, false);
    And here is the position it gives me for the spline.

    Spline Bug.JPG

    For some reason it's returning the position of the 2nd node. I expected it to return the position half way along the ENTIRE spline.

    Am I misunderstanding something?
     
  34. jeffweber

    jeffweber

    Joined:
    Dec 17, 2009
    Posts:
    555
    Any ideas, anyone?
     
  35. nikescar

    nikescar

    Joined:
    Nov 16, 2011
    Posts:
    98
    I have the same question. I need to be able to splineComputer.CalculateLength() to get the spline's total length, then splineComputer.Project(transform.position) to get the percentage of the spline the transform has travelled down the spline, and finally multiply the percentage by the spline's total length to get the distance the transform has travelled.
     
  36. jeffweber

    jeffweber

    Joined:
    Dec 17, 2009
    Posts:
    555
    I did end up getting my answer after submitting a support ticket here it is:

     
  37. nikescar

    nikescar

    Joined:
    Nov 16, 2011
    Posts:
    98
    That works if you already know the distance that you need to evaluate. My problem is that I need to know how far a transform has travelled down a spline in units. In that response, "splineLength / 2f" is what I'm trying to calculate.

    The percentage returned by SplineComputer.Project should have the option to return the uniform value.

    Code (CSharp):
    1. private float GetDistanceTravelled()
    2.     {
    3.         float splineComputerLength = splineComputer.CalculateLength();
    4.         double projectedPercent = splineComputer.Project(trans.position);
    5.         float distanceTravelled = splineComputerLength * projectedPercent;
    6.         return distanceTravelled;
    7.     }
     
    Last edited: Aug 15, 2019
  38. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    Hi, guys,

    Apologies for not being so active on the forums lately. Our studio is expanding this summer and we're super busy. We try to respond to support ques: https://dreamteck.io/support/contact.php within 48 hours.
    We will be responsive again after September when we will release Dreamteck Splines 2 as well.

    @nikescar
    I believe you are after this:
    Code (CSharp):
    1. splineComputer.CalculateLength(0.0, splineComputer.Project(trans.position));
     
    nikescar likes this.
  39. nikescar

    nikescar

    Joined:
    Nov 16, 2011
    Posts:
    98
    Thanks for that answer! I believe that is what I'm looking for but it seems a bit wasteful since I call this every frame and CalculateLength seems rather heavy. I was hoping to be able to cache the length once with splineComputer.CalculateLength() when the spline is changed and then do a calculation against that length using the percentage traveled along the line. Not sure if that is possible.
     
  40. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    You can kind of do that if you sample the spline with a Spline user and set the user to uniform samples and then call the above methods on the Spline User instead of the spline. That way 0.5 would be roughly in the middle of the spline no matter how your points are positioned.
     
  41. nikescar

    nikescar

    Joined:
    Nov 16, 2011
    Posts:
    98
    Great! thanks for the info
     
  42. wesley_unity341

    wesley_unity341

    Joined:
    Dec 14, 2018
    Posts:
    9
    Hi. When calling SetPoints the Spline is rebuilt and the current follower will jump from it's current location to its new location. Presumably based on its parametric value. Is there an easy way to recalculate the current position along the spline after it is rebuilt? Should I just project from world space position onto the spline and update?
     
  43. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    You can cache the follower's position prior to setting the points, the set the points, then project the cached position onto the new spline.
     
  44. polham30

    polham30

    Joined:
    Dec 10, 2015
    Posts:
    2
    Hi, Dreamteck Team.
    I am looking for a way how to add all spline computers to spline projector without dropping FPS.

    I have several spline computers and they connected with each other by using node components.
    I have to jump to another spline computer.
    So I added all spline computers to spline projector.
    Btw fps is dropped from 150 to 20.
    How can I do that?
     
  45. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    228
    Try adding a Spline User component to the Spline Computer and have all projectors sample the Spline User instead of the Spline Computer. Additionally, keep in mind that projection is within the most computationally intensive operations.
     
  46. JeffersonTD

    JeffersonTD

    Joined:
    Feb 5, 2013
    Posts:
    252
    The asset is nice and all, but I'm having one issue. When using SplineRenderer to build a line along some path, and in some parts the curve happens to be more steep than elsewhere, the mesh overlaps with itself. This can be remedied to some extent by adjusting the width at these spots, but it quickly creates a nasty, unpretty compromise. The overlap wouldn't be a problem, if the material wasn't transparent, but it is. So the question is, how do I either
    A) build a shader that takes alpha from the texture, but either only takes one of the overlapping sections into account (like in practice happens if not using transparency) or blends the overlapping sections together before rendering it on top of the other background?
    B) get rid of the overlaps?
     
  47. alan-lawrance

    alan-lawrance

    Joined:
    Feb 1, 2013
    Posts:
    233
    I'm having trouble getting the surface normal of a mesh generated with a spline.

    If you image a road mesh going up/down hills, I want to get the world-space surface normal of the road at any point. If I evaluate the spline at the point I am interested in, I am seeing the normal always being (0,0,1).
     
  48. alan-lawrance

    alan-lawrance

    Joined:
    Feb 1, 2013
    Posts:
    233
    @Dreamteck hoping to get your input on the previous question.
     
  49. alanmthomas

    alanmthomas

    Joined:
    Sep 7, 2015
    Posts:
    149
    I'm not from DreamTeck but I might be able to help. How are you currently going about getting the normal? Theoretically, you should be able to use the GetPointNormal method of the SplineComputer component.
     
  50. alanmthomas

    alanmthomas

    Joined:
    Sep 7, 2015
    Posts:
    149
    I just tested this in my project and it works. Keep in mind that the index of the point that you are passing in is for a point along the spline (the points that you create when you are generating the spline). If what you are looking for is the normal along the path at some percentage of its length (between two of the spline's points), it gets a little more complicated. You want to evaluate the point at its percentage along the path (which will return a SplineResult). That SplineResult will contain the normal at that percentage.