Search Unity

Dreamteck Splines - Powerful and Flexible Spline Solution

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

  1. IanStanbridge

    IanStanbridge

    Joined:
    Aug 26, 2013
    Posts:
    333
    I don't think the idea of ECS is fully baked at this point so it wouldn't make a huge amount of sense switching to it yet. The performance figures aren't really practical because they rely on using cpu cache rather than RAM to get those performance improvements and you have no control on how long a cpu will keep something in cache for because there is so little of it.

    It looks like ECS and the new job system were designed to try and solve the legacy issues of unity being manly single threaded and prefabs always generating cpu cache misses because of them being in a format that a cpu wouldn't cache meaning they are accessed from RAM rather than cache 100 percent of the time.

    ECS still appears to be flawed in that it has moved to the polar opposite. It is trying to make the CPU place entities directly into cache to avoid cache misses by trying to put stuff directly in cache but then it is in effect using cache as ram instead of as cache. Games simply use too much memory for this to be practical. The engine and opperating system should be the one deciding what to cache not the user.

    For example would you want a cpu cache to be filled with spline data ? Whats to say that you have other functions that need that fast access more and if you are running lots of assets that are all using ECS to write to cache then they will simply overflow into ram anyway ?

    The demo Unity is showcasing with all those instance objects was not actually made directly with ECS. it was made using nested prefabs and then Unity made their own custom script that converted those prefabs into ECS code specifically for that demo. They also used features that aren't going to be public till Unity 2019 to achieve that.

    ECS seems very much like the new scriptable render pipeline. The standard unity HD pipeline isn't fully baked yet but you can write your own if you want using beta tools. In reality most people are best off waiting for Unity to finish theirs instead and then building their assets around that.

    I think the more important thing is making assets work well with the new job system as I think that is the future. There is certainly no harm in writting new objects in the new ECS format but I think in reality most calls will still be made to ram rather than cache and Unity will either make a new form of prefab or make a general purpose script that converts prefabs to ECS at build time where the compiler or engine will decide what elements to put into cache to use it most effectively.
     
    Colin_MacLeod likes this.
  2. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    724
    The new required functionality I talked about Seems to be available in Feb 2019.


    Link to see the how it's done 99.5% in ECS.
     
    Last edited: Oct 30, 2018
    Colin_MacLeod likes this.
  3. Colin_MacLeod

    Colin_MacLeod

    Joined:
    Feb 11, 2014
    Posts:
    88
    I'm trying to model a traffic system which traffic that follows predefined paths. I would like as many cars and vehicles as possible, so modeling their behavior feels like a good fit for the ECS/job system model.

    That second vid is really helpful. If you follow the link to the YouTube page, someone has listed out the times various talks start. This is pretty close to what I'm trying to do:

    2:08:47 (11.00AM) ECS: Spline-Based AI Agents

    My app has an "editor" where you layout the road tiles, so I'm wondering whether I can use a SplineUser to save data from Dreamteck Splines into arrays I'll use in an ECS job at runtime
     
  4. doq

    doq

    Joined:
    Aug 17, 2015
    Posts:
    121
    I'm having an issue with the Spline Follower bobbing up and down.

    Any tips on how to get the motion completely smooth?
     
  5. doq

    doq

    Joined:
    Aug 17, 2015
    Posts:
    121
    I figured out the issue. I switched from Hermite to B-Spline and got a much smoother result. In this clip I reduced the point count from 40 to 10 to exaggerate the issue, and then I switched to B-Spline.
     
  6. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    724
    I think for your first example, the sample precision is too low?
    The B-Splines interpolating from point to point, so this is a lot smoother in you case.
     
  7. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    724
    Memory and cache is not like memory and cache. The c# compiler stores the data all over the place into the managed memory. The burst compiler place the native arrays into the fast memory.
     
  8. doq

    doq

    Joined:
    Aug 17, 2015
    Posts:
    121
    Unfortunately, it wasn't an issue with precision. I tried increasing it, and double checked the resolution. Correct me if I'm wrong, but I think it basically comes down to Hermite curves only being C1 vs B-Splines being C2. I was initially hoping to interpolate through the points so that's why I left it as Hermite, but that's not a hard requirement for me. But I am investigating the possibility of curve fitting with B-Splines.

    If anyone has info on how to implement B-Spline curve fitting suitable for mobile and would like to share that'd be appreciated! Approximations are welcome as long as they're smooth! :)
     
  9. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    218
    This is the first time I gotten an error (nothing different in my scene), and I've no idea what it means?

    [Physics.PhysX] cleaning the mesh failed
    UnityEngine.MeshCollider:set_sharedMesh(Mesh)
    Dreamteck.Splines.MeshGenerator:LateRun() (at Assets/Dreamteck/Splines/Components/MeshGenerator.cs:366)
    Dreamteck.Splines.SplineUser:RunMain() (at Assets/Dreamteck/Splines/Components/SplineUser.cs:712)
    Dreamteck.Splines.SplineUser:Update() (at Assets/Dreamteck/Splines/Components/SplineUser.cs:615)

    Actually weirdly I was trying to rotate something by copying a script on it without realizing lol.
     
    Last edited: Nov 2, 2018
  10. doq

    doq

    Joined:
    Aug 17, 2015
    Posts:
    121
    I’m trying to generate very long paths (potentially for an endless runner), so I’m creating multiple SplineComputers (Hermite) and adding PathGenerators to them. I’m reusing the same SplinePoint data for the last point of a spline and the first point of the following spline. But I’m getting a small gap of empty pixels where the splines meet.

    Outside of adjusting the point data to close the gap, does anyone have any suggestions on how to join separate PathGenerators so they’re gapless while maintaining continuity between the end of one spline and the start of the next?

    Thanks
     
  11. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    724
    Hi DreamTeck Team,

    I need a small improvement to rotate the normals in the spline editor. This joystick handle does not work in 3d.
    Untitled-2.jpg


    I tired to include a Handles.RotationHandle() to class SplinePointNormalEditor > SceneEdit but i was not able to handle the normals to rotation and back.

    I did the following to align the Handles.RotationHandle() that is correctly aligned.

    I want to rotate the red local Z normal axis only.

    Untitled-3.jpg

    But how to transfer the variable rot to the get the correct normals for points[selected].normal.zxy ?
    Would you so kind and help with some lines of code please.

    Thank you.
     
    Last edited: Nov 3, 2018
  12. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    724
    BUG#

    The function CalculateBounds() is a bugy. Vector3 max + Vector3 min are wrong initialized.
    That cause the shadow casters to ignore your baked meshes in some cases.
    Code (CSharp):
    1.                 void CalculateBounds()
    2.                 {
    3.                     Vector3 min = Vector3.zero;
    4.                     Vector3 max = Vector3.zero;
    5.                     for (int i = 0; i < vertices.Length; i++)
    6.                     {
    7.                         if (vertices[i].x < min.x) min.x = vertices[i].x;
    8.                         else if (vertices[i].x > max.x) max.x = vertices[i].x;
    9.                         if (vertices[i].y < min.y) min.y = vertices[i].y;
    10.                         else if (vertices[i].y > max.y) max.y = vertices[i].y;
    11.                         if (vertices[i].z < min.z) min.z = vertices[i].z;
    12.                         else if (vertices[i].z > max.z) max.z = vertices[i].z;
    13.                     }
    14.                     bounds.CreateFromMinMax(min, max);
    15.                 }
    16.  
     
  13. Colin_MacLeod

    Colin_MacLeod

    Joined:
    Feb 11, 2014
    Posts:
    88
    Hi Mitko & other Dreamteck Peops!

    I'm trying to set up assembly definition files to add unit testing to our project.

    When I add assembly definition files to the Editor folders of Dreamteck Splines, I'm seeing cyclical dependencies between:
    • Splines/Editor
    • Splines/Components/Editor
    • Utilities/Editor

    I was able to overcome this by restructuring those to:
    • Editor/Splines
    • Editor/Splines/Components
    • Editor/Utilities

    However, now I'm getting a different error:

    • Assets\Dreamteck\Editor\Splines\Tools\FindDerivedClasses.cs(16,49): error CS0234: The type or namespace name 'AssemblyBuilder' does not exist in the namespace 'System.Reflection.Emit' (are you missing an assembly reference?)
    Any ideas? This only seems to happen when I use assembly definition files. If I remove those from my project, it seems to compile fine.

    I'm using Dreamteck Splines 1.0.94 on Unity 2018.3.0b8.

    Thanks,
    Colin
     
  14. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    230
  15. Colin_MacLeod

    Colin_MacLeod

    Joined:
    Feb 11, 2014
    Posts:
    88
    @Dreamteck What's the easiest way to detect a mouseclick on a spline at runtime?
     
  16. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    724
    To determine a click on a spline is not that easy as it seems.

    If you have a mesh that is formed as your spline and you add a mesh collider (for the short time, when the user whats to select splines) then you raycast along the screen space direction from the mouse position and you got a hit.

    But perhaps the dreamteck guys have a another quick solution.
     
    Dreamteck likes this.
  17. Colin_MacLeod

    Colin_MacLeod

    Joined:
    Feb 11, 2014
    Posts:
    88
    Hey @Quantum1000 thanks for taking the time. Yes, that makes sense. Would be great if there were an easier way :)
     
  18. ben_unity9

    ben_unity9

    Joined:
    Sep 21, 2017
    Posts:
    5
    Hello Dreamteck team,

    I am having trouble finding a way to create "caps" to a UV a UV mapped spline.
    See the start of my path is very abrupt and I would like to start it with a cap.
    upload_2018-11-27_18-9-5.png

    Is there a way to do this and I missed it??

    thanks!
    Ben
     
  19. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    230
    Yes, what @Quantum1000 said. The best way would be to use a tube generator for collision (having the mesh renderer disabled). Other ways would include sampling the spline and converting to screen space to detect if the mouse is contained, which is definitely not very effective.
     
    Colin_MacLeod likes this.
  20. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    230
    If you are using the SplineMesh component, you can add a new channel for the cap meshes and set it to Place instead of Extrude. That will create caps for you.
     
  21. ben_unity9

    ben_unity9

    Joined:
    Sep 21, 2017
    Posts:
    5
    Hey thanks, I got it now. It seems promising, I need to setup my meshes differently.
     
    Dreamteck likes this.
  22. darrencperry

    darrencperry

    Joined:
    Jan 22, 2014
    Posts:
    20
    Hey Dreamteck!

    Is it possible when animating the Spline Positioner Percentage or Distance, to preview that in the editor? When we hook up Anim Position we can't scrub this in the editor outside of play mode in Animation or Timeline with Preview enabled...

    Cheers!
     
  23. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    230
    Yes, but you will need to write a custom script to attach to the animated SplinePositioner and implement OnDidApplyAnimationProperties and add a position property to that script and animate it instead of the spline positioner:
    https://forum.unity.com/threads/why...applyanimationproperties-undocumented.481600/
    Inside, you can call positioner.SetPercent(percent); to update the positioner's percent.

    We are looking into adding native support for this but there are a few obstacles right now.
     
  24. darrencperry

    darrencperry

    Joined:
    Jan 22, 2014
    Posts:
    20
    Super tip, thanks guys!
     
    Flurgle likes this.
  25. Flurgle

    Flurgle

    Joined:
    May 16, 2016
    Posts:
    368
    @darrencperry Did you manage to get it working? I'd love to see this implemented.
     
  26. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    724
    Hi DreamTech,

    A) var n = new SplineResult() cause 104bytes GC as a local help variable.
    Did you have a performance solution for this?

    B) Result.Rotation() internal use public Quaternion Rotation() to calculate the rotation every time on access. I already have optimized Rotation() but its too slow anyway. I have nowhere animated splines, so I want to completely prevent calculation of Rotation();

    Here is an optimized working example what happen each time on Quaternion.LookRotation() behind the scenes. The original Unity LookRotation use the double amount of code by the simpler Vector commands.
    Code (CSharp):
    1.         public static Quaternion QuaternionLookRotation(Vector3 forward, Vector3 direction) {
    2.  
    3.             double quaternion_w;
    4.             double quaternion_x;
    5.             double quaternion_y;
    6.             double quaternion_z;
    7.  
    8.             double direction_x = direction.x;
    9.             double direction_y = direction.y;
    10.             double direction_z = direction.z;
    11.  
    12.             // ... forward.Normalize();
    13.             double forward_x = forward.x;
    14.             double forward_y = forward.y;
    15.             double forward_z = forward.z;
    16.  
    17.             const double dEpsilon = 9.99999974737875E-06;
    18.  
    19.             // ... num0 = Math.Sqrt(forward_x * forward_x + forward_y * forward_y + forward_z * forward_z);
    20.             double num0 = CaboVar.FastSqrt(forward_x * forward_x + forward_y * forward_y + forward_z * forward_z);
    21.             if (num0 > dEpsilon) {
    22.                 forward_x /= num0;
    23.                 forward_y /= num0;
    24.                 forward_z /= num0;
    25.             } else {
    26.                 forward_x = 0;
    27.                 forward_y = 0;
    28.                 forward_z = 0;
    29.             }
    30.  
    31.             // ... Vector3 vector = Vector3.Normalize(forward);
    32.             // ... Vector3 vector = forward;
    33.             double vector_x = forward_x;
    34.             double vector_y = forward_y;
    35.             double vector_z = forward_z;
    36.  
    37.             // ... Vector3 vector2 = Vector3.Normalize(Vector3.Cross(up, vector));
    38.             double vector2_x;
    39.             double vector2_y;
    40.             double vector2_z;
    41.  
    42.             /// Vector3.Cross(up, vector)
    43.             vector2_x = direction.y * vector_z - direction.z * vector_y;
    44.             vector2_y = direction.z * vector_x - direction.x * vector_z;
    45.             vector2_z = direction.x * vector_y - direction.y * vector_x;
    46.  
    47.             /// Vector3.Normalize( vector2 )
    48.             // ... num0 = Math.Sqrt(vector2_x * vector2_x + vector2_y * vector2_y + vector2_z * vector2_z);
    49.             num0 = CaboVar.FastSqrt(vector2_x * vector2_x + vector2_y * vector2_y + vector2_z * vector2_z);
    50.             if (num0 > dEpsilon) {
    51.                 vector2_x /= num0;
    52.                 vector2_y /= num0;
    53.                 vector2_z /= num0;
    54.             } else {
    55.                 vector2_x = 0d;
    56.                 vector2_y = 0d;
    57.                 vector2_z = 0d;
    58.             }
    59.  
    60.             // ... Vector3 vector3 = Vector3.Cross(vector, vector2);
    61.             double vector3_x;
    62.             double vector3_y;
    63.             double vector3_z;
    64.  
    65.             vector3_x = vector_y * vector2_z - vector_z * vector2_y;
    66.             vector3_y = vector_z * vector2_x - vector_x * vector2_z;
    67.             vector3_z = vector_x * vector2_y - vector_y * vector2_x;
    68.  
    69.             double num8 = (vector2_x + vector3_y) + vector_z;
    70.  
    71.             if (num8 > 0d) {
    72.                 // ... var num = Math.Sqrt(num8 + 1d);
    73.                 var num = CaboVar.FastSqrt(num8 + 1d);
    74.                 quaternion_w = num * 0.5d;
    75.                 num = 0.5d / num;
    76.                 quaternion_x = (vector3_z - vector_y) * num;
    77.                 quaternion_y = (vector_x - vector2_z) * num;
    78.                 quaternion_z = (vector2_y - vector3_x) * num;
    79.                 return new Quaternion((float)quaternion_x, (float)quaternion_y, (float)quaternion_z, (float)quaternion_w);
    80.             }
    81.  
    82.             if ((vector2_x >= vector3_y) && (vector2_x >= vector_z)) {
    83.                 // ... var num7 = Math.Sqrt(((1d + vector2_x) - vector3_y) - vector_z);
    84.                 var num7 = CaboVar.FastSqrt(((1d + vector2_x) - vector3_y) - vector_z);
    85.                 var num4 = 0.5d / num7;
    86.                 quaternion_x = 0.5d * num7;
    87.                 quaternion_y = (vector2_y + vector3_x) * num4;
    88.                 quaternion_z = (vector2_z + vector_x) * num4;
    89.                 quaternion_w = (vector3_z - vector_y) * num4;
    90.                 return new Quaternion((float)quaternion_x, (float)quaternion_y, (float)quaternion_z, (float)quaternion_w);
    91.             }
    92.  
    93.             if (vector3_y > vector_z) {
    94.                 // ... var num6 = Math.Sqrt(((1d + vector3_y) - vector2_x) - vector_z);
    95.                 var num6 = CaboVar.FastSqrt(((1d + vector3_y) - vector2_x) - vector_z);
    96.  
    97.                 var num3 = 0.5d / num6;
    98.                 quaternion_x = (vector3_x + vector2_y) * num3;
    99.                 quaternion_y = 0.5d * num6;
    100.                 quaternion_z = (vector_y + vector3_z) * num3;
    101.                 quaternion_w = (vector_x - vector2_z) * num3;
    102.                 return new Quaternion((float)quaternion_x, (float)quaternion_y, (float)quaternion_z, (float)quaternion_w);
    103.             }
    104.  
    105.             // ... var num5 = Math.Sqrt(((1d + vector_z) - vector2_x) - vector3_y);
    106.             var num5 = CaboVar.FastSqrt(((1d + vector_z) - vector2_x) - vector3_y);
    107.             var num2 = 0.5d / num5;
    108.             quaternion_x = (vector_x + vector2_z) * num2;
    109.             quaternion_y = (vector_y + vector3_z) * num2;
    110.             quaternion_z = 0.5d * num5;
    111.             quaternion_w = (vector2_y - vector3_x) * num2;
    112.             return new Quaternion((float)quaternion_x, (float)quaternion_y, (float)quaternion_z, (float)quaternion_w);
    113.         }
    114.  



    I have to following solution, would that work?

    Add a new field to SplinResult.cs
    Code (CSharp):
    1. public class SplineResult {
    2.  
    3.         public Vector3 Position = Vector3.zero;
    4.         public Vector3 Normal = Vector3.up;
    5.         public Vector3 Direction = Vector3.forward;
    6.         public Quaternion RotationFixed = Quaternion.identity; <---------------------
    7.         public double Percent = 0.0;
    8.         .............
    9.  
    On EvaluateComputer() I added
    Code (CSharp):
    1.  
    2.             ...........
    3.             internalResult.Direction.Normalize();
    4.             internalResult.RotationFast = internalResult.Rotation;  <----------------------
    5.             return internalResult;
    6.         }
    7.  
    Would that work on internal create the samples and use RotationFast directly?
    I know this will raise the sample memory amount.
     
    Last edited: Dec 24, 2018
  27. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    230
    1. It's not the local variable that creates GC but the creation of new SplineResult objects. This is why we have the non-allocating methods for evaluation where you can create the variable outside the method and just pass it as a reference.

    2. We are probably going to stick with our current rotation method. We don't usually use it in our code ans when we do, we cache the result so we don't call it more than we have to.

    And by the way the name of our studio is actually "Dreamteck" (with a "k" at the end and no other capital letters) :D

    Happy holidays, everyone!
     
  28. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    724
    Yes sorry, the reason for is I'm working on https://dreamtech.co/ daily. Sometimes it screw up a bit.

    What? :D You don't use result.rotation in your project code.. and if, you cache ??

    If your objects should follow a path by direction, there is no way to prevent result.rotation at any time. Caching can be performed only before the all the action happen, and caching all splines (with extra code logic) to prevent using result.rotation is exactly what I did in the small example above.

    Can you elaborate your caching method "cache the result so we.." please! Would be great to lean a bit from how you doing it. Thank you.
     
  29. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    230
    Yes, of course:
    I'm not talking about caching the whole rotations result in an array but simply caching it before using it multiple times.

    Code (CSharp):
    1. Quaternion rotation = result.rotation;
    2. a.rotation = offsetRotation * rotation;
    3. b.rotation = rotation;
     
  30. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    724
    Ah okay, misunderstood you. Yes for sure :)

    1) Did you thought about to use quaternion in a sample and use
    Quaternion.Slerp, Quaternion.Lerp instead of use direction & normal and would that work without geometry issues (rotation) ?

    2) I have some issues to invert the point order. How to inverse all the normals are saved to the points. The following code does so far, but the points[x].normals seems to be wrong after inverse the point order. Would you so kind and help here please.

    Code (CSharp):
    1.         void InvertPointOrder() {
    2.             var pointInvert = new SplinePoint[points.Length];
    3.             // ... Copy by value
    4.             for (int i = 0; i < pointInvert.Length; i++) {
    5.                 pointInvert[i] = points[i];
    6.             }
    7.  
    8.             for (int i = 0; i < points.Length; i++) {
    9.                 points[i] = pointInvert[pointInvert.Length - i - 1];
    10.  
    11.                 var h = points[i].tangent;
    12.                 points[i].SetTangentPosition(points[i].tangent2);
    13.                 points[i].SetTangent2Position(h);
    14.  
    15.                 points[i].normal... ?
    16.  
    17.                // Is there a node connected then rework the node conections as well.
    18.  
    19.             }
    20.             UpdateComputer();
    21.         }
    22.  
    Thank you.
     
    Last edited: Jan 1, 2019
  31. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    3,595
    Ullukai and Dreamteck like this.
  32. superjayman

    superjayman

    Joined:
    May 31, 2013
    Posts:
    138
    Window->Dreamteck->Spline Tools does NOT WORK! in Unity 2018.3.5.

    It does not open the the Tools window, and throws the following error

    Exception of type 'System.Reflection.ReflectionTypeLoadException' was thrown.
     
  33. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    724
    Can you post the complete error including the complete text from the console.
     
  34. Johny_Boy

    Johny_Boy

    Joined:
    Jun 6, 2017
    Posts:
    5
    Hello, I am French and I translated my problem.
    I hope you can help me.
    So already congratulations for the tool, it is really top.
    But I have a little problem with it and I do not quite understand what's going on.
    I created a splineComputer as a child of an empty object. I am associated with 4 nodes. and I confided in "Space" => local
    I then created a splineFollower object, to which I associate the splineComputer. I created a little script that activates me the splineFollower (The script increments the followspeed from 0 to 1 when triggerstay on it)
    Good during the game I instantiate all the object, and when my player arrives on the trigger, the splinefollower is played at this local position only if I put pause and that I click on it in the hierarchy. otherwise he follows his path in the world position, ie far from where he is instantiated.
    It's very hard to explain and I do not understand how to solve this problem.
    Do you have an idea ? Hoping to have managed to explain correctly.
    thank you
     
  35. Johny_Boy

    Johny_Boy

    Joined:
    Jun 6, 2017
    Posts:
    5
    Ok ! The option build an awake is not checked by default and this seems to solve my problem
     
  36. Djaydino

    Djaydino

    Joined:
    Aug 19, 2012
    Posts:
    25
    HI. How can you do the Inverse Point Order From Script?
     
  37. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    724
    There is an internal function that does. But inverse the point order cause some ugly results if the spline is connected to any other spline/s by a node/s. Invers the point order does not take case of the nodes, means the nodes exchange the node position.
     
    Dreamteck likes this.
  38. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    230
    This is correct. We will add an option for InversePointOrder that will retain nodes for future use cases.
     
    Quatum1000 likes this.
  39. 13Flo

    13Flo

    Joined:
    Jun 9, 2015
    Posts:
    93
    @Dreamteck I'm considering Dreamteck Spline for my project and I'd like to have more information about how branching works. Basically, in the case of a road that splits in 2, is the generated mesh "merged" or simply overlapped? Is there a video tutorial about how that works? Thanks!
     
  40. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    230
    Branching just logically connects the splines together and provides a way to find the connected splines at the point of branching. The road meshes will just overlap. The solution to this is to use a custom junction mesh and attach the branching nodes to it so that the branched roads connect properly to the road.
    Here is a video on nodes and junctions:
    And you can read about nodes in the user manual: https://dreamteck.io/page/1
     
    13Flo likes this.
  41. Nodrap

    Nodrap

    Joined:
    Nov 4, 2011
    Posts:
    48
    I am trying to establish if a point is off the end of a spline using the Project fn and was expecting either 1 or 0 for when a point was past the end but I seem to get values like 0.9997 or 0.0003. Am I doing something wrong and is there a solution. Thanks
     
  42. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    230
    If you are using SplineComputer.Project, then this is expected because of the subdivision nature of the algorithm. We will look for a way to improve this in future versions but checking for percent >= 0.999 and percent <= 0.001 should be enough to tell if you are at the very end.
     
  43. Nodrap

    Nodrap

    Joined:
    Nov 4, 2011
    Posts:
    48
    Code from SplineComputer.cs is failing when I start at the end of a spline and travel backwards because the end of a spline is 1 and so it drops out as start IS >=1. I'd suggest clamping to 1 and continuing.

    Code (CSharp):
    1.        public double Travel(double start, float distance, Spline.Direction direction)
    2.         {
    3.             if(pointCount <= 1) return 0.0;
    4.             if (start >= 1.0) return 1.0;
    5.             if (distance == 0f) return DMath.Clamp01(start);
    6.             float moved = 0f;
    7.  
     
    Dreamteck likes this.
  44. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    230
    Noted! Thanks!
     
  45. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    230
    We just released Dreamteck Splines 1.0.96 with a lot of bug fixes and something very exciting:
    Dreamteck Splines is now compatible and supported by our newest product - Forever.

    Forever is an endless runner system and it bends the Dreamteck Splines along its own splines. That's technically splineception.


    Now here is the changelog for 1.0.96:

    FIX: Fixed the issue with the Spline Users not updating in edit mode if they are part of a prefab instance in Unity 2018.3 or higher
    FIX: Improved spline evaluation performance and direction computation accuracy
    FIX: Fixed the SplinePrefs colors not loading properly and loading while instad (Go to Preferences->DTK Splines->Use Defaults to get the fix)
    FIX: The spiral primitive generator now properly generates the spiral shape (broken in previous updates)
    FIX: Editing clip range values for channels inside the Spline Mesh editor now works properly
    FIX: Improved the performance of the Object Bender component
    FIX: The Object Bender now properly bends objects along all axes (broken in previous version)

    REMOVED: Removed "Average Result Vectors" from the SplineUser component as it is now obsolete and bad for performance

    FEATURE: Added a custom Up and Forward option to the Object Bender component to further help customize the results
    FEATURE: Added a "Build on Enable" option to the SplineUser component which will make sure that the SplineUser updates every time it has been disabled and re-enabled
    FEATURE: The ObjectController component now has the option (on by default) to retain prefab connections when in Editor mode

    API: The AddTrigger methods inside the SplineTracer have re-arranged parameters
    API: Starting from 1.0.96 Dreamteck Splines adds a "DREAMTECK_SPLINES" scripting define to the existing defines in the Player settings - useful for checking if Dreamteck splines is installed in the project.
     
    Last edited: Mar 20, 2019
    zKici and JLO like this.
  46. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    230
    We are slowly starting work on Dreamteck Splines 1.1. Version 1.1. will not be entirely compatible with 1.0.96 as there will be some core changes in the way our system works. This is all going to be for the better but some projects that are further into development with 1.0 might be problematic in terms of switching over to the new version. We will make sure that the new version warns everyone prior to installation and makes it clear that things will change. Here's what's on the roadmap:

    1. SplineComputers will now store the spline samples inside - SplineUsers will no longer sample the splines individually - the sample targets will be removed
    2. Multithreading will now happen using a single thread manager
    3. Multi-object editing for SplineComputers in the editor
    4. When modifying splines, only the samples around the modified point(s) will be re-calculated instead of sampling the entire spline again
    5. Precision will be replaced with "Sample Rate" - an integer number allowing you to specify exactly how many samples between each two points will be calculated
    6. A new Object Controller component will be introduced that works similarly to the Spline Mesh component - with layers and much more control (we're open for suggestions for a good name for that new component)
    7. The MeshExtrude component will be removed from the package - it has been obsolete for almost an year now.
    8. Junctions will no longer be created using Nodes. Instead, spline points will be connected directly. The Nodes will stay and the old logic for junctions will remain in the package but their main purpose from now on will be to just link spline points to world objects - not provide junction functionality.
    9. Optimization feature: a new option for reducing spline samples will be introduced. It will remove samples along straight segments of the splines as long as the spline and generated geometry stay visually the same (optional - can be toggled on and off).
    10. New spline editor - the spline editing tools are moving from the Scene View to the Editor Inspector in order to follow Unity's design pattern for tools.
    11. The "Remove Inner Faces" for meshes inside the Spline Mesh component will make a return. We had this option long time ago in the ExtrudeMesh - now we're bringing it back for the Spline Mesh.
    12. Option to edit the spline points in Local space inside the inspector.


    More features will be added but these are the main ones. Dreamteck Splines 1.1 should be ready around June this year.

    We're also making a new awesome video for the tool and are looking for videos of projects, made with Dreamteck Splines. We want to include and credit them in the video. So if you'd like to be on the video, send us a link to some game footage (1080p, 30fps) at team@dreamteck.io
     
    Last edited: May 5, 2019
    JLO likes this.
  47. TFPolygon

    TFPolygon

    Joined:
    Mar 4, 2015
    Posts:
    2
    Hey! I think your Tools namespace conflicts with Amplify Shader Editor Tools or something.
    The type or namespace name 'current' does not exist in the namespace 'Tools' (are you missing an assembly reference?)
     
  48. cristims

    cristims

    Joined:
    Dec 21, 2012
    Posts:
    24
    Hi.
    I just brought your pack and so far is great but I have couple of questions.

    1. Is there a way to control via outside script what node-connected splines the follow object will move to? For example if I have a node connection and I need to change the path during run-time from a spline to another, how do I do it? Are there any exposed methods on that particular Node, like "switch" to change from a path to another? That will be super nice, to command a node to change the path during runtime.

    2. I need to have a train moving along a spline and I kind of wish to have it slow down on steep curves, accelerate downhill and slow uphill. Is there a way to automate this or I have to use the triggers?

    3. I think the triggers are great, but it will be nice to have more methods to control the follow objects, like "accelerate/decelerate, with a bit of easing/lerp" so that when we hit a trigger and we want to change the speed to do it gradually.

    So far I have a blast with the pack. I love it, works so smooth and is a real joy to see how many options you have to place objects along it.
    Great job!

    [Edit]
    Sorry but I need to ask you one more question.
    4. Is there a way to "link/drag" the wagons to the locomotive along the spline and only hook the locomotive to the "follow" script?
     
    Last edited: May 4, 2019
  49. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    230
    Thank you for using Dreamteck Splines!

    The answer to most of your questions lies in the Examples package. Inside Dreamteck/Splines you will find a unitypackage file called "Examples. There you will find an example for junction switching (Nodes/Junctions.unity).

    The Roller Coaster example contains a script which automates the speed based on the steepness (via Vector3.Dot).

    Easing of the speed is up to you. The followSpeed property of the Spline Follower is exposed for you. You can then control it using an AnimationCurve for example. Just set it to your desire.

    For the last question, you can use a SplinePositioner along with the Travel method. Get the percent of the follower ahead, then move back *wagon length* using the Travel method to find the position for the wagon. Do the rest for each wagon.
     
  50. Dreamteck

    Dreamteck

    Joined:
    Feb 12, 2015
    Posts:
    230
    That shouldn't be happening - all of our scripts are enclosed in our own namespace. Maybe ask Amplify to check their scripts for the same?